2014-01-10 31 views
1

我有一個函數void foo(const std::string& s),我想用foo(s.substr(pos))來調用。C++ 11是否允許參考匿名臨時文件

在MSVC(實現C++ 98)中,這個編譯好,但是posix的舊編譯器會出錯,「不能引用匿名臨時文件」。這讓我覺得在標準C++ 98中不允許引用匿名臨時表。

但是,在C++ 11中允許嗎?

+0

什麼是 「POSIX的編譯器」?上面的代碼肯定會被GCC和Clang所接受。如果你刪除了'const',它只會失敗 - 這也會使VC++失敗,而不依賴於C++ 98或C++ 11。 –

+0

我想我讀過SO,只要它是**對const對象**的引用,就可以引用一個匿名臨時對象。你的情況是哪一個。 –

+0

這是[完全合法的C++](http://ideone.com/G4la9d),並且自從C++ 98(以及可能之前)以來。你的「posix編譯器」不正確。 –

回答

2

C++ 98以及C++ 11在將const引用綁定爲參數時接受臨時文件。以下作品:

void foo(const std::string& s); 

foo(s.substr(pos)); // OK 

如果你想利用非const引用,標準/編譯器認爲這是你需要的修改後的結果暗示,這是不可能的訪問,因爲它是一個臨時的。因此,下面不工作:

void foo(std::string& s); 

foo(s.substr(pos)); // not OK 

注意與C++ 11,你可以重載foo檢測右值,這是臨時對象。 (還有其他人):

void foo(std::string& s); // 1 
void foo(std::string&& s); // 2 

foo(s.substr(pos)); // calls 2 
+1

MSVC *會*將一個臨時對象綁定到一個非''const'引用,這可能是OP不記得的。 – Casey

+0

@Casey VC會因'/ Za'(禁用語言擴展)而失敗,或者警告您足夠高的警告級別('/ W4'?我沒有使用VC ...) –

1

請問C++ 11允許採取引用匿名臨時?

是的,絕對是。 C++ 03也是如此。有條件...

在MSVC(實現C++ 98),這編譯好,但posix的舊編譯器會錯誤,「不能引用匿名臨時」。這讓我覺得在標準C++ 98中不允許引用匿名臨時表。

我覺得你在記憶中略有不同。首先,所有的臨時是「匿名」,並且它們都可以被綁定到一個基準TO- const(綁定延伸臨時的壽命,但在下面的例子中,即使是沒有必要的):

int foo(const T&); 
int x = foo(T()); 

這在標準C++和以前都是這種情況。如果你的舊POSIX編譯器不接受它,那麼它是非常糟糕的;不過,我相信你而不是想着下列情況:

int foo(T&); // no `const` 
int x = foo(T()); 

這是合法的,但Visual Studio中()接受它作爲一種誤導非標準的例外,因爲微軟。