С++ functor и функциональные шаблоны
рассмотрим этот простой и бессмысленный код.
#include <iostream>
struct A {
template<int N>
void test() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a.test<1>();
}
Это очень простой пример шаблона функции. Что если, однако, я хотел бы заменить A::test
на перегруженный operator()
, чтобы сделать его функтором?
#include <iostream>
struct A {
template<int N>
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a<1>(); // <-- error, how do I do this?
}
Конечно, если operator()
взял параметры, зависящие от шаблона, компилятор мог бы вывести шаблон. Но я просто не могу понять правильный синтаксис, чтобы указать параметры шаблона с помощью безпараметрического функтора.
Есть ли правильный способ сделать это?
Очевидно, что этот код будет работать, поскольку он обходит синтаксис функтора:
a.operator()<1>();
но этот вид побеждает цель его функционала: -P.
Ответы
Ответ 1
Нет другого "прямого" способа, который я знаю, кроме:
a.operator()<1>();
синтаксис. Если вы открыты для изменения кода, перемещение параметра шаблона в класс будет работать или с помощью (boost | tr1):: bind, чтобы создать объект (boost | tr1):: function.
Ответ 2
Вы можете звонить только
a.operator()<1>();
но это не будет использовать функтор. Функторам нужен оператор non template(), поскольку они должны быть вызваны как varname(), и это не будет работать с вашим кодом.
Чтобы сделать его реальным функтором, измените свой код на класс шаблона (функторы - это классы):
#include <iostream>
template<int N>
struct A {
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A<1> a;
a();
}
Ответ 3
Вы пытаетесь передать параметр шаблона экземпляру объекта, который, насколько мне известно, не разрешен. Вы можете передавать только параметры шаблонов в функции шаблона или объекты шаблона.
a.test < 1 > (); и a.оператор() < 1 > (); потому что они служат в качестве функций шаблона.
Используйте boost:: bind (проверьте библиотеки ускорения), чтобы исправить это.
struct A {
void operator()(int n) {
std::cout << n << std::endl;
}
};
int main(int argc, char* argv[]) {
A a;
boost::function<void()> f = boost::bind<void>(a, 1);
f(); // prints 1
return 0;
}
И вам даже не нужно возиться с шаблонами!
Ответ 4
Ты застрял. Вы считали что-то вроде
struct A {
template<int N>
struct B
{
void operator()()
{ std::cout << N << std::endl; }
};
template<int N>
B<N> functor() {return B<N>();}
};
int main()
{
A a;
a.functor<1>()();
}
Ответ 5
Нет, нет. Как вы сказали, вам нужно либо явно вызвать оператор (который побеждает цель), либо аргументы шаблона должны быть выведены компилятором.