Передавать функцию как явный параметр шаблона
В приведенном ниже примере кода вызов 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;
}
Ответы
Ответ 1
Проблема здесь: 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;
}
Ответ 2
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);