21

以下のコード例では、への呼び出しは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;
}
4

2 に答える 2

37

ここでの問題は、タイプ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;
}
于 2012-06-03T14:25:40.907 に答える
7

multiplyタイプではなく、関数です。そのコンテキストでは、関数ポインタに減衰します。ただし、barこれもそうではないタイプ用にテンプレート化されてmultiplyいます。

Nawazはすでに逆の質問(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);
于 2012-06-03T14:28:22.033 に答える