my new Event class: template variadics and how test a valid function\lambda

Pages: 12
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
JLBorges: why the test_event() it's const?
Coder777: is there anyway for be Implicit?
thanks to all
> 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
like i know: if test_event it's const, i can't edit after the 1st time(constructor).
but thanks for all... thank you
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.
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?
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.
Pages: 12