2012-06-03 89 views
15

在下面的代码示例中,对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; 
} 
+0

另请参阅[函数作为模板参数传递](https://stackoverflow.com/q/1174169/608639)。 – jww

回答

26

这是问题所在,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

谢谢你的明确解释! – tajmahal

7

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); 
+0

如果他打算使用这个,那么他还需要更改'bar'。语法'F(x,y)'应该变成'F(x,y)()'。 – Nawaz

+0

@Nawaz不,''类型'实际上不是一个函子。它只是一个具有合适的构造函数和流输出过载的类型(在这种情况下,合适的转换运算符已经具有流输出过载)。 (请参阅http://ideone.com/AgQGc) –

+0

Ohh ..我忽略了...可能是因为函子会是一个更好的选择,因此我期待着那样。 – Nawaz

相关问题