2012-08-14 93 views
0

時,我有以下代碼:傳遞baz重載決議函數模板傳遞給另一個函數

template<typename T> 
void bar(int x, T y) 
{ 
} 

void baz(int x, int y) 
{ 
} 

template<typename T0, typename T1> 
void foo(void k(T0, T1), T1 t) 
{ 
} 

int main() 
{ 
    foo(baz, 10); // OK 
    foo(bar, 10); // ERROR 
    return 0; 
} 

超載分辨率foo正常工作。但是,在傳遞函數模板bar時,編譯器無法推斷foo的模板參數T0,即使範圍中只有一個bar,並且其第一個參數完全解析爲int。如何編寫功能模板foo,以便類似foo(bar, 10)這樣的調用可以由編譯器解決?

回答

0

14.8.2.1/6(從函數調用推導模板參數)回答了這個:

P是一個函數類型,函數指針類型或成員函數指針類型:

  • 如果參數是包含一個或多個函數模板的重載集,則該參數將被視爲非推導的上下文。

在你的情況,bar是一個函數模板,從而論證k是函數類型,其重載集包含函數模板。因此bar<T>的模板參數不能被推斷。

作爲一個實際的原因,考慮到foo(bar<int>, 10)foo(bar<long>, 10)都是完全可行的調用,並且不會爲您隱式選擇。請記住,整數文字的類型取決於,如果foo(bar, 10)foo(bar, 100000000)產生了不同的模板專業化,那將會很奇怪。

+0

是的,我明白了爲什麼我當前的例子是不可抵扣的原因。我的問題是如何重寫函數模板'foo'?換句話說,是否有一些幫助可以在函數定義站點而不是呼叫站點提供編譯器,這樣可以工作?函數模板作爲參數並不是前所未有的。例如,'std :: endl'是一個函數模板。 – keveman 2012-08-14 23:10:54

+0

@keveman「_例如,std :: endl是一個函數模板。」但是'basic_ostream :: operator <<'不是! – curiousguy 2012-08-16 23:13:20

0

你可以這樣做:

void (&b)(int,int) = bar; 
    foo(b, 10); 
相關問題