Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Definition of an array of pointer-to-members in combination with variadic templates

In an embedded application, I'd like to create a helper class which holds a list of pointer-to-member-functions of a certain class, where the helper class calls the member functions in succession. At the moment, I'm having troubles with the definition statement of the static array which holds the pointers. This is the code:

template<class C, class F>
struct FunctionSequence;

template<class C, class R, class... Args>
struct FunctionSequence<C, R(Args...)>
{
    typedef R(C::*PointerToMember)(Args...);

    template<PointerToMember... F>
    struct Type
    {
        static const PointerToMember f[sizeof...(F)];
    };
};

template<class C, class R, class... Args>
template<typename FunctionSequence<C, R(Args...)>::PointerToMember... F>
const typename FunctionSequence<C, R(Args...)>::PointerToMember
    FunctionSequence<C, R(Args...)>::Type<typename FunctionSequence<C, R(Args...)>::PointerToMember... F>::f[sizeof...(F)]
        = { F... };

struct Test
{
    void m1(int) {}
    void m2(int) {}

    FunctionSequence<Test, void(int)>::Type<&Test::m1, &Test::m2> fs;
};

Both Visual Studio 2013 and GCC 4.7.3 give errors on this line, where I'm trying to define the f variable, and initialize it with a list of the member function pointers:

FunctionSequence<C, R(Args...)>::Type<typename FunctionSequence<C, R(Args...)>::PointerToMember... F>::f[sizeof...(F)]

GCC gives the following errors:

expansion pattern 'typename FunctionSequence<C, R(Args ...)>::PointerToMember' contains no argument packs
too many template-parameter-lists

Visual Studio gives the following errors:

error C3546: '...' : there are no parameter packs available to expand
error C2146: syntax error : missing ',' before identifier 'F'
error C3545: 'F': parameter pack expects a non-type template argument

Moreover, Visual Studio gives an additional error one line later:

error C3855: 'FunctionSequence<C,R(Args...)>::Type<F...>': template parameter 'F' is incompatible with the declaration

Is it even possible what I am trying to do? Is my code wrong, and is it fixable?

like image 505
Richard Avatar asked Jan 21 '14 09:01

Richard


2 Answers

Turn @dyp comment into answer:

Don't use typename outer<T>::type V as template parameter.

You have to declare it that way:

template<class C, class R, class... Args>
template<R(C::*...F)(Args...)>
const typename FunctionSequence<C, R(Args...)>::PointerToMember
    FunctionSequence<C, R(Args...)>::Type<F...>::f[sizeof...(F)]
        = { F... };
like image 128
Jarod42 Avatar answered Oct 27 '22 09:10

Jarod42


Why are you trying to initialize it outside of class, if you can simply do this in C++11?

template<class C, class R, class... Args>
struct FunctionSequence<C, R(Args...)>
{
    typedef R(C::*PointerToMember)(Args...);

    template<PointerToMember... F>
    struct Type
    {
        static constexpr PointerToMember f[sizeof...(F)] = {F...};
    };
};
like image 2
ForEveR Avatar answered Oct 27 '22 09:10

ForEveR