Определение массива указателей на члены в сочетании с шаблонами переменных

Во встроенном приложении я хотел бы создать вспомогательный класс, который содержит список функций указателя на член определенного класса, где вспомогательный класс последовательно вызывает функции-члены. В данный момент у меня проблемы с оператором определения статического массива, который содержит указатели. Это код:

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;
};

И Visual Studio 2013, и GCC 4.7.3 выдают ошибки в этой строке, где я пытаюсь определить переменную f и инициализировать ее списком указателей на функции-члены:

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

GCC выдает следующие ошибки:

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

Visual Studio выдает следующие ошибки:

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

Более того, Visual Studio выдает дополнительную ошибку на одну строку позже:

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

Возможно ли даже то, что я пытаюсь сделать? Мой код неверен и это поправимо?

2 ответа

Решение

Преврати комментарий @dyp в ответ:

Не использовать typename outer<T>::type V в качестве параметра шаблона.

Вы должны заявить об этом так:

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... };

Почему вы пытаетесь инициализировать его вне класса, если вы можете просто сделать это в 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...};
    };
};
Другие вопросы по тегам