2014-12-10 5 views
0

Я хочу, чтобы указатель функции указывал на функцию, которая принимает в качестве аргумента класс с параметром шаблона (см. main). Я считаю, что я близок к правильному синтаксису, но получаю ошибку компиляции: «объявление шаблона не может появляться в области блока».Указатели функций с шаблонами

#include <iostream> 
#include <array> 

template<int N> 
class NumberHolder 
{ 
public: 
    NumberHolder(); 
    int x_; 
}; 

template<int N> 
NumberHolder<N>::NumberHolder() : x_(N) {} 

template<int N, int M> 
void add(NumberHolder<N>& nh) 
{ 
    nh.x_ += M; 
} 

template<int N, int M> 
void mult(NumberHolder<N>& nh) 
{ 
    nh.x_ *= M; 
} 

int main() 
{ 
    NumberHolder<3> nh; 

    //using f_ptr = void(*)(NumberHolder<3>&); // Compiles 
    template<int N> using f_ptr = void(*)(NumberHolder<N>&); // Doesn't compile 

    std::array<f_ptr, 2> operations; 
    operations[0] = &add<3, 41>; 
    operations[1] = &mult<3, 8>; 

    for (int i = 0; i < operations.size(); ++i) 
    { 
    operations[i](nh); 
    } 
    std::cout << nh.x_ << std::endl; 
    return 0; 
} 
+0

Вы можете приблизиться к этому только с помощью шаблонов * C++ 14 *. Но те, что и все шаблоны, не могут быть объявлены локально. – dyp

+1

В любом случае вы не можете использовать шаблон класса в качестве класса или шаблон переменной в качестве переменной. В словах Стефана Т. Лаваджея: «Вы не можете есть резак для печенья». 'std :: array ' поэтому не может быть законным: 'f_ptr' является шаблоном, а' std :: array' ожидает, что тип будет первым аргументом шаблона. – dyp

ответ

1

Вы должны переместить шаблон псевдоним за пределами локальной области видимости:

template <int N> using f_ptr = void (*)(NumberHolder<N>&); 

int main() 
{ 
    const std::array<f_ptr<3>, 2> operations {&add<3, 41>, &mult<3, 8>}; 
    NumberHolder<3> nh; 

    for(const auto& operation : operations) { 
     operation(nh); 
    } 
    std::cout << nh.x_ << std::endl; 
    return 0; 
} 

Live example.

Смежные вопросы