Передать функцию как явный параметр шаблона

В приведенном ниже примере кода вызов 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);
Другие вопросы по тегам