2010-08-22 63 views
4

以下的小例子的參考變量顯示我的問題:問題通過模板參數

template<class T> struct X 
{ 
    static void xxx(T& x) { } 
    static void xxx(T&& x) { } 
}; 

int main(int argc, char** argv) 
{ 
    int x = 9; 
    X<int>::xxx(x); // OK. 
    X<int&>::xxx(x); // ERROR! 
    return 0; 
} 

錯誤消息(GCC):

error: ‘static void X::xxx(T&&) [with T = int&]’ cannot be overloaded
error: with ‘static void X::xxx(T&) [with T = int&]’

爲什麼呢? T = int& --->T&取代int&&static void xxx(T& x)

如果問題的答案是肯定的,那麼:

  • T&不是一個左值引用,並將其變成右值參考!
  • 而下面的代碼應工作:

但事與願違:

template<class T> struct X 
{ 
    static void xxx(T& x) { } 
}; 

int main(int argc, char** argv) 
{ 
    X<int&>::xxx(2); // ERROR! 
    return 0; 
} 

錯誤消息(GCC):

error: no matching function for call to ‘X::xxx(int)’
note: candidates are: static void X::xxx(T&) [with T = int&]

然後T&T = int&不等於T&&並不是右值參考。但如果不是,爲什麼第一個例子不起作用? (這是一個遞歸問題!)


但對於指針類型並沒有出現類似的問題:

#include <iostream> 

template<class T> struct X 
{ 
    static void xxx(T* x) { std::cout << **x << std::endl; } 
}; 

int main(int argc, char** argv) 
{ 
    int x = 10; 
    int* xx = &x; 
    X<int*>::xxx(&xx); // OK. call X<int*>::xxx(int**) 
    return 0; 
} 

爲什麼引用是這種行爲有什麼不同?

+1

我的頭很疼。很多&符號。 – 2010-08-22 17:51:37

+3

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&& @詹姆斯&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& – GManNickG 2010-08-22 18:05:46

回答

10

的C++語言的11標準有是如何工作的一個解釋§8.3.2[dcl.ref/6(重新格式化爲可讀性):

If a typedef, a type template-parameter, or a decltype-specifier denotes a type TR that is a reference to a type T ,

  • an attempt to create the type "lvalue reference to cvTR " creates the type "lvalue reference to T "
  • an attempt to create the type "rvalue reference to cvTR " creates the type TR .

讓我們考慮你的榜樣(I」 VE更名爲您TTR所以它的語言相匹配以上):

template<class TR> struct X 
{ 
    static void xxx(TR& x) { } 
    static void xxx(TR&& x) { } 
}; 

如果我們試圖實例XTR = int&(所以,T = int)的xxx的實例是如下:

static void xxx(TR& x) { } --> static void xxx(int& x) { } 
static void xxx(TR&& x) { } --> static void xxx(int& x) { } 

在第一種情況,我們試圖創建一個「左值參照TR」,它變成「左值參照T」。 Tint,所以參數類型變爲int&

在第二種情況下,我們嘗試創建一個「右值引用TR」,它變爲TR,它是int&

參數類型對於兩個重載都是相同的,因此是錯誤。

+1

我約70%相信你已經完全記住了規範 – 2010-08-22 18:06:46

+0

感謝表達TR的意義。 – 2010-08-22 18:19:00

+0

這是使'std :: forward'工作的規則嗎?也就是說,每個C++ 0x程序員都必須知道這個...... :) – UncleBens 2010-08-22 18:24:09