[英]Temporary non-const istream reference in constructor (C++)
似乎一個對istream采用非const引用的構造函數不能用C ++中的臨時值構造。
#include <iostream>
#include <sstream>
using namespace std;
class Bar
{
public:
explicit Bar(std::istream& is) {}
};
int main()
{
istringstream stream1("bar1");
Bar bar1(stream1); // OK on all platforms
// compile error on linux, Mac gcc; OK on Windows MSVC
Bar bar2(istringstream("bar2"));
return 0;
}
這與MSVC編譯良好,但不與gcc編譯。 使用gcc我得到一個編譯錯誤:
g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:18: error: no matching function for call to ‘Bar::Bar(std::istringstream)’
test.cpp:9: note: candidates are: Bar::Bar(std::istream&)
test.cpp:7: note: Bar::Bar(const Bar&)
構造Bar對象的第二種方式(bar2)是否存在哲學上的錯誤? 它對我來說看起來更好,並且不需要只需要片刻的stream1變量。
編輯 :回應約翰內斯紹布的評論,我想提供更多的背景。 首先,這不是我第一次被C ++的這種行為所困擾,所以我真的對這個問題的更高層次的哲學討論感興趣。 也就是說,在這種特殊情況下,我有一個類,它讀入包含用於構造對象的數據的文件。 我也喜歡編寫使用字符串而不是文件的自動化測試。 但使用該文件進行構建是主要用例。 所以我決定創建一個帶有istream的構造函數,所以我可以使用文件(流)或字符串(流)。 這就是我到這里的方式。 我的測試程序直接從字符串構造對象,以模擬讀取文件。 這為我節省了為每個小測試創建單獨數據文件的麻煩。
這就是C ++當前的工作原理:您不能將非const引用綁定到臨時對象。 MSVC允許這樣做是非標准的。
C ++ 0x將具有r值引用並在此處稍微改變一下。 人們試圖對這個問題的雙方都有各種各樣的哲學解釋 - 但我沒有找到一個完全令人信服的解釋。 似乎更多的是“你必須選擇一種行為並堅持下去”,這解釋了當前的C ++和0x的變化:所選擇的行為已經發生了變化。
Roger是對的......這是C ++的通用策略,只有const引用可以綁定到臨時對象。 我不認為右值引用會對您有所幫助,因為在傳遞非臨時流的情況下,您確實希望繼續使用其修改狀態。
更重要的是,為什么不用friend
提取器替換構造函數istream &operator>>(istream &s, Bar &b)
? 以向對象添加未初始化狀態為代價,語法將更加C ++ - ish。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.