簡體   English   中英

構造函數中的臨時非const istream引用(C ++)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM