[英]When can't an object be converted to a reference?
我想從http://code.google.com/p/enhsim編譯以下代碼行:
enh::eout << enh::setw(26);
gcc給出以下錯誤:
error: no match for 'operator<<' in 'enh::eout << enh::setw(26)'
但是EnhSimOutput
類(其中enh::eout
是一個實例)確實聲明:
EnhSimOutput& operator<< (setw& p);
如果我實現一個按值接受對象的操作版本,這個問題就消失了:
EnhSimOutput& operator<< (setw p);
或者如果我將enh::setw
對象創建為本地對象,即:
enh::setw wValue(26);
enh::eout << wValue;
我的問題是:為什么gcc不選擇運營商的“按引用”版本開頭?
編寫此代碼的開發人員明確地將其編譯,但默認gcc拒絕執行此操作。 為什么單獨聲明為局部變量的對象與本地創建的內聯之間存在差異?
值enh::setw(26);
是一個左值 。 實際上,像這樣的臨時工具是價值。 Rvalues有特殊屬性。 其中一個是他們的地址不能被采用( &enh::setw(26);
是非法的),並且他們通常不能綁定到非const的引用(一些臨時可以綁定到非const的引用,但是這些經歷了特殊規則:通過引用非const來調用臨時對象上的成員函數並捕獲異常對象。在后一種情況下,臨時甚至是左值 。
有兩種表達式: lvalues表示對象(進而可以存儲值)或函數, rvalues表示從對象讀出的值或由臨時值,數字文字和枚舉器常量表示的值。 在C ++ 03中,為了能夠將這些值傳遞給接受其引用值的函數,有一條規則可以通過引用接受它們: setw const& p
會接受它。 也就是說,您必須像這樣聲明您的運算符:
EnhSimOutput& operator<< (setw const& p);
這有點不幸,因為你不能消除常量左值(使用const enh::setw e(26);
你在堆棧上創建的對象)和非const或const rvalues(如enh::setw(26);
歧義enh::setw(26);
這是一個非const臨時的)。 此外,如果你這樣做,參數不能在其上調用非const成員函數,因為它是一個const的引用。 出於這個原因,下一個C ++版本的C ++ 1x引入了一種新的引用,即所謂的rvalue-references ,它修復了這種情況。
Microsoft Visual C ++編譯器將rvalues綁定到對非const的引用,但在執行此操作時會發出警告(您必須至少使用警告級別4才能顯示它)。 這是不幸的,因為當移植到標准合規性更嚴格的其他編譯器時問題會增加。
我的猜測是EnhSimOutput& operator<< (setw& p);
通過非const引用傳遞,但值26是“const”,因為它不能被修改。 嘗試將其設置為EnhSimOutput& operator<< (const setw& p);
或嘗試
int nNumber = 26;
enh::eout << enh::setw(nNumber);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.