2013-11-09 22 views
6

標準C++類型,如int或焦有構建函數,這樣就可以有這樣的表達式:通過引用傳遞一個匿名可變

int a = int(67); // create anonymous variable and assing it to variable a 
int b(13);  // initialize variable b 
int(77);   // create anonymous variable 

用戶定義的類型(結構或類)能夠做同樣的:

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

STRUCT c = STRUCT(67); 
STRUCT d(13); 
STRUCT(77); 

問題是:爲什麼我們可以通過引用匿名結構或類實例傳遞,但不能傳遞標準類型?

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

void func1(int& i){} 
void func2(STRUCT& s){} 
void func3(int i){} 
void func4(STRUCT s){} 

void main() 
{ 
    //func1(int(56)); // ERROR: C2664 
    func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference 
    func3(int(46)); // OK: anonymous int is created then assigned to a parameter 
    func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter 
} 
+4

您的'func2'行不應該編譯(出於與第一個相同的原因)。 – Mat

+0

'void main()'是非標準的。 –

+0

在適當的警告級別下,您將得到'警告C4239:使用非標準擴展名:'參數':從'STRUCT'轉換爲'STRUCT&';非const引用只能綁定到左值。你應該使用'/ W4'。 –

回答

2

如果您的編譯器允許這樣做,那麼它不是標準兼容的C++編譯器。您不能將臨時右值綁定到非常量左值引用。這是規則。 clanggcc都不會編譯func2(STRUCT(65));的代碼。

相反,你必須選擇:從C++ 03

void func1(int&& i){} 

void func1(const int& i){} 

遺產:A(左值)參考應該能夠在非const類型(int &i)來改變參數然後使臨時對象例如因爲56不合邏輯,因爲它不可更改。對const類型(const int &i)的引用應該只是將該值視爲只讀,然後傳遞臨時值(例如52)是合法的。

在C++ 11中,您可以通過&&引用非const的臨時對象。

5

看來你使用的MS VC++編譯器有這樣的bug :)你必須綁定臨時對象與const引用。例如,您可能寫

const int &ri = 10; 

但你可能不寫

int &ri = 10; 

同樣是有效的用戶定義的類型。

const STRUCT &rs = STRUCT(10); 

STRUCT &rs = STRUCT(10); // the compiler shall issue an error. 
0

在C++中,一個匿名臨時對象始終是一個right-value.To接受權值作爲參數,可以:

1).void foo1(TYPE); //傳遞值
2).void foo2(const TYPE &); //傳遞const參考
3).void foo3(TYPE & &); //在C++ 11中,通過右值引用

您的「func3」和「func4」接受通過值傳遞的參數,沒關係。
但是,「func1」和「func2」只能接受由左值引用傳遞的參數。所以傳遞匿名參數是錯誤的。