2012-09-04 123 views
4

今天我只想提出一個關於C++ 11(我使用vs2010 sp1)的C++模板函數參數演繹和模板函數重載解析的問題。 我已經定義如下兩個模板功能:C++模板函數參數演繹和函數解析

函數#1:

template <class T> 
void func(const T& arg) 
{ 
    cout << "void func(const T&)" <<endl; 
} 

功能#2:

template <class T> 
void func(T&& arg) 
{ 
    cout << "void func(T&&)" <<endl; 
} 

現在考慮下面的代碼:

int main() { 
    //I understand these first two examples: 

    //function #2 is selected, with T deduced as int& 
    //If I comment out function #2, function#1 is selected with 
    //T deduced as int 
    {int a = 0; func(a);} 

    //function #1 is selected, with T is deduced as int. 
    //If I comment out function #1, function #2 is selected, 
    //with T deduced as const int&. 
    {const int a = 0; func(a);} 

    //I don't understand the following examples: 

    //Function #2 is selected... why? 
    //Why not function #1 or ambiguous... 
    {func(0);} 

    //But here function #1 is selected. 
    //I know the literal string 「feng」 is lvalue expression and 
    //T is deduced as 「const char[5]」. The const modifier is part 
    //of the T type not the const modifier in 「const T&」 declaration. 
    {func(「feng」)} 

    //Here function#2 is selected in which T is deduced as char(&)[5] 
    {char array[] = 「feng」; func(array);} 
} 

我只是想知道在這些情景下指導功能重載分辨率的規則IOS。

我不同意下面的兩個答案。我認爲const int示例與字面字符串示例不同。我可以修改#function 1位,看看有什麼在const int的例子在地球上

template <class T> 
void func(const T& arg) 
{ 
    T local; 
    local = 0; 
    cout << "void func(const T&)" <<endl; 
} 
//the compiler compiles the code happily 
//and it justify that the T is deduced as int type 
const int a = 0; 
func(a); 

template <class T> 
void func(const T& arg) 
{ 
T local; 
Local[0] = ‘a’; 
cout << "void func(const T&)" <<endl; 
} 
//The compiler complains that 「error C2734: 'local' : const object must be  
//initialized if not extern 
//see reference to function template instantiation 
//'void func<const char[5]>(T (&))' being compiled 
    // with 
    // [ 
    //  T=const char [5] 
    // ] 

Func(「feng」); 

推導的類型,在「常量牛逼&」聲明const修飾吃掉const int的的「常量性」 ;而在字面字符串示例中,我不知道「const T &」聲明中const修飾符的位置在哪裏。聲明一些像int & const是沒有意義的(但是聲明int * const是有意義的)

+2

我已經修改了你的問題做出了很多更具可讀性,但我放棄了一些章節,我無法理解。請閱讀新版本並重新添加您認爲重要的任何內容(而且我錯過了)。 – Mankarse

+1

@Leonid:你在吸菸?你想要一個*非const的左值*被推斷爲右值參考?這是瘋狂。 T推導爲「int&」是完全正確的。 – Puppy

+0

@DeadMG - 你是對的,它被推斷爲'int&'。我已經從'func()'打印的內容剪切和粘貼了,而沒有考慮它。 –

回答

5

這裏的技巧是const。 F1和F2都可以接受任何類型的任何值,但是F2通常是更好的匹配,因爲它是完美的轉發。所以除非值是const左值,否則F2是最好的匹配。但是,當左值是const時,F1是更好的匹配。這就是爲什麼它最好是const int和字符串文字。

1

請注意,過載#2與T &和T & &完全匹配。所以兩個重載都可以綁定到右值和左值。在你的例子中,重載差異主要是基於常量完成的。

//Function #2 is selected... why? 
//Why not function #1 or ambiguous... 
{func(0);} 

0int&& - 精確匹配爲T&&

//But here function #1 is selected. 
//I know the literal string 「feng」 is lvalue expression and 
//T is deduced as 「const char[5]」. The const modifier is part 
//of the T type not the const modifier in 「const T&」 declaration. 
{func(「feng」)} 

文字"feng"const char(&)[5] - 在第一次過載const T&精確匹配。 (&)表示這是一個參考。

//Here function#2 is selected in which T is deduced as char(&)[5] 
{char array[] = 「feng」; func(array);} 

陣列 - 是char(&)[5] - 在第二次過載T&精確匹配

+0

我期望'{func(0);}'採用'const T&'版本。爲什麼選擇T &&?在這種情況下,T是'const int'。 –

+0

不,'0'是'int &&' - 標準是這樣說的。 –

+0

我不同意你的觀點,我補充一些證據。 – changFeng