my new Event class: template variadics and how test a valid function\lambda
Jun 22, 2016 at 9:38am UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include <iostream>
#include <functional>
template < typename ... ARGS > struct event
{
event() = default ;
template < typename FN > event( FN fn ) : callback(fn) {} // converting constructor
const event& operator () ( ARGS... args ) const { if (callback) callback(args...) ; return *this ; }
private : std::function< void ( ARGS... ) > callback = nullptr ;
};
struct timer
{
template < typename FN > timer( FN fn ) : timer_callback(fn) {} // converting constructor
void test() const { std::cout << "*** test *** timer - " ; timer_callback() ; } // only for exposition
// ...
private : event<> timer_callback ;
};
int main()
{
const event<int > test_event( []( int arg ) { std::cout << "*** test **** event<int> - arg == " << arg << '\n' ; } ) ;
test_event(99) ;
timer my_timer( [] { std::cout << "tick!\n" ; } ) ;
my_timer.test() ;
}
http://coliru.stacked-crooked.com/a/0e3be77a36d586d1
http://rextester.com/SWSEF12194
Jun 22, 2016 at 7:13pm UTC
JLBorges: why the test_event() it's const?
Coder777: is there anyway for be Implicit?
thanks to all
Jun 22, 2016 at 7:23pm UTC
> why the test_event() it's const?
Force of habit; if something can be declared
const , declare it as
const .
For the rationale, see:
http://www.cplusplus.com/forum/beginner/180986/#msg888218
EDIT: In this toy snippet,
my_timer could also be a
const object, though a real life timer object is unlikely to be a
const object.
Last edited on Jun 22, 2016 at 7:28pm UTC
Jun 22, 2016 at 7:32pm UTC
like i know: if test_event it's const, i can't edit after the 1st time(constructor).
but thanks for all... thank you
Jun 23, 2016 at 7:52am UTC
is there anyway for be Implicit?
What do you mean by 'Implicit'? If you want to pass both
Event
and the lambda to
Timer
use the constructor
JLBorges showed on line 16.
Jun 24, 2016 at 8:26pm UTC
JLBorges: see that i'm trying overloading the operator '=':
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
template < typename ... ARGS > struct Event2
{
public :
Event2() = default ;
template < typename FN > Event2( FN fn ) : callback(fn) {} // converting constructor
const Event2& operator () ( ARGS... args ) const { if (callback) callback(args...) ; return *this ; }
bool IsValid()
{
if (callback)
return true ;
else
return false ;
}
Event2 &operator =(std::function<void (ARGS... args)> Event)
{
callback=Event;
}
private : std::function< void ( ARGS... ) > callback = nullptr ;
};
when i use it:
1 2 3 4 5 6 7 8 9 10 11 12 13
Event2<int , int > test{[](int a, int b)
{
MessageBox("hello world 1: " + to_string(a+b));
}};
//overloading operator '=':
test(3,4);//works
test=[](int a, int b)
{
MessageBox("hello world 2: " + to_string(a*b));
};
test(4,5);
error message:
- ambiguous overload for 'operator=' (operand types are 'Event2<int, int>' and 'WinMain(HINSTANCE, HINSTANCE, LPSTR, int)::__lambda222::__lambda239');
Cadidates are:
Event2<ARGS>& Event2<ARGS>::operator=(std::function<void(a ...)>) [with ARGS = {int, int}]
what i'm doing wrong?
Jun 25, 2016 at 12:57am UTC
clang++ emits an easy to understand diagnostic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include <iostream>
#include <functional>
template < typename ... ARGS > struct Event2
{
public :
Event2() = default ;
template < typename FN > Event2( FN fn ) : callback(fn) {} // converting constructor
const Event2& operator () ( ARGS... args ) const { if (callback) callback(args...) ; return *this ; }
bool IsValid()
{
if (callback)
return true ;
else
return false ;
}
Event2 &operator = ( std::function<void (ARGS... args)> Event ) { callback = Event ; return *this ; }
private : std::function< void ( ARGS... ) > callback = nullptr ;
};
int main()
{
Event2<int , int > test{ [] (int a, int b) { std::cout << "1. " << a+b << '\n' ; } };
test(3,4);//works
test = [] (int a, int b) { std::cout << "2. " << a*b << '\n' ; } ; // *** error
test(4,5);
}
main.cpp:30:10: error: use of overloaded operator '=' is ambiguous ...
main.cpp:4:38: note: candidate is the implicit move assignment operator
main.cpp:4:38: note: candidate is the implicit copy assignment operator
main.cpp:20:13: note: candidate function Event2 &operator = ( std::function<void(ARGS... args)> Event ) ...
http://coliru.stacked-crooked.com/a/231e61a33d4c81a1
Since the constructor is a converting constructor, the simplest solution is to remove the custom assignment operator (then there would be no ambiguity; the implicitly declared move assignment operator would be selected).
http://coliru.stacked-crooked.com/a/d16050e414ca81fd
Topic archived. No new replies allowed.