2013-07-24 49 views
0

我遇到了一個奇怪的情況,即編譯器選擇投射結構,即使有一個完美的構造函數接收結構類型。
一個小例子:構造函數重載選擇投射運算符而不是結構類型

struct A 
{ 
    operator int() {return 1;} 
}; 

struct B 
{ 
    B(A& a) { OutputDebugStringA("A constructor\n"); } 
    B(int i) { OutputDebugStringA("int constructor\n"); } 
}; 
A test() { A a; return a;}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    B b(test()); 
    return 0; 
} 

說明:具有轉換運算符爲int。 具有重載的構造,一個接受參考,和一個接受INT
函數test()返回一個A對象。

由於某些原因,編譯器決定將返回值轉換爲int類型,並使用接受int的構造函數。 int constructor

任何人都可以解釋爲什麼會發生這種情況?我有一些理論,但我想要一個基於真實的答案(也許是標準的引用)。

注:
我可以通過改變構造函數簽名,以獲得預期的結果(構造函數接受的類型):B(const A& a)B(A&& a)

回答

5

你的構造函數需要一個非const引用A,不能結合到一個臨時的。在這裏你傳遞一個臨時的:

B b(test()); 
// ^^^^^^ temporary A 

所以唯一有效的構造是一個服用int。在C++ 11

B(const A& a) { OutputDebugStringA("A constructor\n"); } 
//^^^^^ 

,類似的還有B(A&& a);:您可以通過相關的構造採取const參考更改此行爲。

另外,保持了原有的構造函數簽名和傳遞一個左值也導致構造函數調用:

A a; 
B b(a); 
+0

葉氏,我認爲這可能是一個事實,即它是一個右值做。 –

+0

'B(A && a)'可以在C++ 11中使用,就像'template T&unmove(T && t){return t; ''額外的罪惡。 – Yakk