(我問在comp.std.C++這個問題的變化,但沒有得到答案。)的C++ 0x右值引用和臨時
電話爲什麼要f(arg)
在此代碼調用const ref超載f
?
void f(const std::string &); //less efficient
void f(std::string &&); //more efficient
void g(const char * arg)
{
f(arg);
}
我的直覺說,f(string &&)
過載應選擇,因爲arg
需要被轉換成一個臨時的不管是什麼,以及臨時的右值引用比左值基準更好的匹配。
這不是在
GCC和
MSVC(編輯:感謝Sumant:在GCC 4.3-4.5中沒有發生)中發生的情況。至少在
G ++和
MSVC中,任何左值都不會綁定到右值引用參數,即使有也存在臨時創建的中間值。的確,如果const ref overload不存在,編譯器會診斷錯誤。但是,編寫f(arg + 0)
或f(std::string(arg))
確實如您所期望的那樣選擇右值引用超載。
從我讀的C++ 0x標準看來,當考慮f(string &&)
是否可行時,應該考慮將const char *隱式轉換爲字符串,就像傳遞const lvalue ref參數時一樣。第13.3節(重載決議)在太多地方不區分右值參考和常量參考。此外,似乎阻止左值綁定到右值引用(13.3.3.1.4/3)的規則不應該適用於臨時存在中間值的情況 - 畢竟,臨時移動是完全安全的。
是這樣的:
- 我誤讀/誤解的標準,在實施的行爲是預期的行爲,並有一些很好的理由,爲什麼我的例子應該表現它的方式?
- 編譯器供應商以某種方式產生的錯誤?還是基於共同實施策略的錯誤?或者在例如GCC(這個左值/右值引用綁定規則是第一次實現的),這是由其他供應商複製的?
- 標準中的缺陷,或意想不到的後果,還是應該澄清的事情?
編輯:我有一個後續的問題是相關的:C++0x rvalue references - lvalues-rvalue binding
在給定的情況下,爲什麼會超載更快?一個字符串對象必須以某種方式創建,並綁定一個引用。 – UncleBens 2010-05-01 08:11:16
@UncleBens:假設函數將其參數存儲在某個全局變量/成員變量中 - 如果已知該參數是可移動的,那麼它可以移動到目標中,而不是被複制。 – Doug 2010-05-01 08:21:01