Передать функцию как явный параметр шаблона
В приведенном ниже примере кода вызов foo
работает, пока звонок bar
выходит из строя.
Если я закомментирую звонок bar
, код компилируется, что говорит мне определение bar
сам в порядке. Так как бы bar
правильно называться?
#include <iostream>
using namespace std;
int multiply(int x, int y)
{
return x * y;
}
template <class F>
void foo(int x, int y, F f)
{
cout << f(x, y) << endl;
}
template <class F>
void bar(int x, int y)
{
cout << F(x, y) << endl;
}
int main()
{
foo(3, 4, multiply); // works
bar<multiply>(3, 4); // fails
return 0;
}
2 ответа
Проблема здесь в том, multiply
не тип; это значение, но шаблон функции bar
ожидает, что аргумент шаблона будет типом. Отсюда и ошибка.
Если вы определите шаблон функции как:
template <int (*F)(int,int)> //now it'll accept multiply (i.e value)
void bar(int x, int y)
{
cout << F(x, y) << endl;
}
тогда это будет работать. Посмотреть онлайн демо: http://ideone.com/qJrAe
Вы можете упростить синтаксис, используя typedef
как:
typedef int (*Fun)(int,int);
template <Fun F> //now it'll accept multiply (i.e value)
void bar(int x, int y)
{
cout << F(x, y) << endl;
}
multiply
это не тип, это функция. В этом контексте он распадается на указатель на функцию. Тем не мение, bar
шаблон для типа, который, опять же, multiply
не является.
Наваз уже ответил на вопрос наоборот (как изменить определение bar
для использования с функциями), но чтобы ответить на ваш явный вопрос о том, как вызвать bar
как вам это нужно, вам нужен подходящий тип, например:
struct Type {
const int result;
Type(int x, int y): result(x * y) {}
operator int() const { return result; }
};
// usage
bar<Type>(x, y);
// (edit) a suitable type doesn't necessarily mean a new type; this works as well
// if you aren't trying to solve any specific problem
bar<std::string>(64, 64);