2012-06-03 45 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

相關問題