2012-01-01 62 views
4

我有一個正常工作的重載函數。 (在這個例子中是f)。當我將它轉換爲同一事物的模板版本時,它總是調用T &版本,而不是T *。 (在這個例子中是t)當我製作一個模板函數的非const版本時,它按預期工作。 (在這個例子中爲t2)VS2010和g ++ 4.6.2都會出現這種情況。推廣到const規則是不同的,還是這是某種錯誤。爲什麼我的重載模板函數提升爲不同的const,然後是非模板函數。

#include <iostream> 
using namespace std; 

int f(const int&x){return 1;} 
int f(const int*x){return 2;} 

template <class T> int t(const T &x){return 3;} 
template <class T> int t(const T *x){return 4;} 

template <class T> int t2(T &x){return 5;} 
template <class T> int t2(T *x){return 6;} 

int main(int argc, char ** argv){ 
    int x=0; 
    cout<<f(x)<<endl; 
    cout<<f(&x)<<endl; 
    cout<<t(x)<<endl; 
    cout<<t(&x)<<endl; 
    cout<<t2(x)<<endl; 
    cout<<t2(&x)<<endl; 
    return 0; 
} 

輸出是

1 
2 
3 
3 
5 
6 
+0

更多解釋:t((const int *)&x)按預期工作。 – 2012-01-01 19:51:27

+2

+1,用於一個簡短的完整測試用例。 – 2012-01-01 19:51:37

回答

5

int xconst。所以&x產生一個int*。這裏有兩個候選功能:

  • int t<int*>(T const&)(等同int t<int*>(int * const&))< - T是int*;需要0次轉換
  • int t<int>(T const*)(等同於int t<int>(int const*))<-T是int;需要從int*int const*的轉換

選擇更好的匹配,即沒有轉換的匹配。這是參考版本。

2

在這兩種情況:

cout<<t(x)<<endl; 
cout<<t(&x)<<endl; 

template <class T> int t(const T &x)過載正由編譯器選擇的,因爲T可以通過分別intint *,來滿足。

在這種情況下:

cout<<t2(&x)<<endl; 

template <class T> int t2(T &x)過載沒有被選擇,因爲它不能得到滿足。您不能將引用綁定到臨時(右值),並且&x是臨時的。

+0

必須有一個原因,然後引用rvalues。因爲如果我創建一個指針變量來保存右值,它仍然調用相同的函數。 int * p =&x; T2(P); - > 6 – 2012-01-02 02:10:59