functions variables

why i can do:

classname(std::function<voi(...)> func)//class construtor\function parameter

but not:

std::function<voi(...)> func;//variable name
???
Last edited on
It works for me:
http://ideone.com/QIsSbq
Can you give a more concrete example?
sorry you miss something the variadic operator ;)
you used the types of, variables and works fine but i mean use the '...' operator
You can't use that with std::function by design - there is no specialization of std::function that handles variadic arguments after the normal arguments.

Instead you need to use variadic templates.
so for my situaction, i prefere continue using my own macro:

#define event(eventname, ... ) std::function<void(__VA_ARGS__ )> eventname
several programmers advice me for not use macros, but seems that i must use some
Use a tuple to hold the parameters:

#define event(eventname, ... ) std::function<void(std::tuple<__VA_ARGS__> )> eventname
Last edited on
sorry... i never sod 'tuple'... why use it instead the 'function'?
Something like this, perhaps (perfect forwarding elided for simplicity):

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
33
34
35
36
#include <iostream>
#include <functional>
#include <vector>


template < typename... ARGS > struct event
{
    template < typename FN >
    void subscribe( FN fn ) { subscribers.emplace_back(fn) ; }

    void fire( ARGS... args ) { for( auto& fn : subscribers ) fn(args...) ; }

    std::vector< std::function< void(ARGS...) > > subscribers ;
};

struct A
{
    int value() const { return value_ ; }
    void value( int new_value ) { value_ = new_value ; value_changed.fire( value_, *this ) ; }

    template < typename FN > void subscribe( FN fn ) { value_changed.subscribe(fn) ; }

    private:
         int value_ = 0 ;
         event< int, const A& > value_changed ;
};

int main()
{
    A a ;
    a.subscribe( [] ( int v, const A& ) { std::cout << "first subscriber: value changed to " << v << '\n' ; } ) ;
    a.value(99) ;
    std::cout << "\nadd another subscrption\n----------------\n" ;
    a.subscribe( [] ( int v, const A& ) { std::cout << "subscriber 2: value changed to " << v << '\n' ; } ) ;
    a.value(-37) ;
}

http://rextester.com/BRCDB59697
Problem with std::tuple is the only STL way to access its members is std::get which requires knowing the index of the member you want at compile-time, and it's complicated to do it at runtime: http://ideone.com/gquXzP

This took about five minutes to compile on Ideone.
> This took about five minutes to compile on Ideone.

On coliru (logic is different):

clang++     compile: 1.135 seconds,     run: 0.008 seconds

g++-4.9     compile: 1.082 seconds,     run: 0.006 seconds


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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <tuple>
#include <vector>

namespace detail
{
    template < typename TUPLE, std::size_t CURR, std::size_t SIZE >
    struct printer
    {
        static std::ostream& print( std::ostream& stm, const TUPLE& tup )
        {
            stm << ", " << std::get<CURR>(tup) ;
            return printer< TUPLE, CURR+1, SIZE >::print( stm, tup ) ;
        }
    };

    template < typename TUPLE, std::size_t SIZE > struct printer<TUPLE,0,SIZE>
    {
        static std::ostream& print( std::ostream& stm, const TUPLE& tup )
        {
            stm << "{ " << std::get<0>(tup) ;
            return printer< TUPLE, 1, SIZE >::print( stm, tup ) ;
        }
    };

    template < typename TUPLE, std::size_t SIZE > struct printer<TUPLE,SIZE,SIZE>
    { static std::ostream& print( std::ostream& stm, const TUPLE& ) { return stm << " }" ; } };

    template < typename TUPLE > struct printer< TUPLE, 0, 0 >
    { static std::ostream& print( std::ostream& stm, const TUPLE& ) { return stm << "{}" ; } };
}

template < typename... TYPES >
std::ostream& operator<< ( std::ostream& stm, const std::tuple<TYPES...>& tup )
{ return detail::printer< std::tuple<TYPES...>, 0, sizeof...(TYPES) >::print( stm, tup ) ; }

enum weekday { monday, tuesday, wednesday, thursday, friday, saturday, sunday } ;

std::ostream& operator<< ( std::ostream& stm, weekday wd )
{
    static const char* const txt[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Satudrday", "Sunday" } ;
    return stm << ( wd >= monday && wd <= sunday ? txt[wd] : "??????" ) ;
}

int main()
{
    using tuple_type = std::tuple< weekday, int, std::string > ;
    const std::vector<tuple_type> todo_list = {
        tuple_type{ monday,  900, "purchase meat" },
        tuple_type{ tuesday, 1400, "beat meat" },
        tuple_type{ wednesday, 1100, "make sandwiches" },
        tuple_type{ thursday, 1200, "eat sandwiches" },
        tuple_type{ friday, 1200, "reinvent wheel" },
        tuple_type{ saturday,  800, "post cats" },
        tuple_type{ sunday, 2200, "post sinks (mods asleep)" }
    };
    for( auto& tup : todo_list ) std::cout << tup << '\n' ;
}

http://coliru.stacked-crooked.com/a/2a879c8521d47d04
sorry, but i will continue with my macro.
i understand that you will avoid me the macros, but it's the best, in these case ;)
thanks to all
Topic archived. No new replies allowed.