2010-03-09 87 views
1

似乎无法使用C++中的临时值构造将istream的非const引用构造函数。构造函数中的临时非const istream引用(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变量。

编辑:为了回应Johannes Schaub的评论,我想给出更多的上下文。首先,这不是我第一次被C++的这种行为所困扰,所以我真的对这个问题的更高层次的哲学讨论感兴趣。也就是说,在这种特殊情况下,我有一个读入包含用于构造对象的数据的文件的类。我也喜欢编写使用字符串而不是文件的自动化测试。但使用该文件进行构建是最主要的用例。所以我决定创建一个采用istream的构造函数,所以我可以使用文件(流)或字符串(流)。我就是这样来的。我的测试程序直接从字符串构造对象,以模拟读取文件。这为我节省了为每个小测试创建单独数据文件的麻烦。

+1

您可以通过'istringstream(“bar2”)。seekg(0)'作为解决方法。 – 2010-03-09 00:44:32

+0

MSVC行为是一个非标准的扩展,它会产生一个警告,我想如果你启用标准模式(/ Za),你也会得到一个错误。 – 2010-03-09 00:45:45

+0

@Johannes Schaub:非常聪明。我想任何返回对临时对象的引用的方法都可以在这里使用。 – 2010-03-09 00:52:33

回答

3

这就是C++目前的工作原理:不能将非常量引用绑定到临时对象。 MSVC在允许这个方面是非标准的。

C++ 0x将有r值引用,并在这里改变一些东西。人们试图对问题—的双方申请—有各种哲学解释,但我没有找到一个完全有说服力的解释。看起来更像是“你只需要选择一种行为并坚持下去”,它解释了当前的C++和0x的变化:所选择的行为已经发生了变化。

+0

你是说构造“Bar bar2(istringstream(”bar2“));”将在下一个C++标准中工作?那样就好了。 – 2010-03-09 00:57:22

+0

@Christopher,你需要重载构造函数,比如'explicit Bar(std :: istream&){..} explicit Bar(std :: istream &&){..}'。然后第一个将抓取所有左值(主要是变量),第二个抓取所有右值(大部分是像你的临时值)。 – 2010-03-09 01:04:31

+0

差不多,我说你可以像Johannes所说的那样使它工作,但并不是说你现在的代码会奇迹般地在0x中工作。 – 2010-03-09 01:08:51

1

罗杰是正确的......这是C++的通用策略,只有const引用可能绑定到临时对象。不过,我不认为右值引用会对你有所帮助,因为在传递非临时流的情况下,想要继续使用它的修改状态。

更重要的是,为什么不用friend提取器istream &operator>>(istream &s, Bar &b)替换构造函数?以向对象添加未初始化状态为代价,语法将更加C++ - ish。

+0

+1您的运营商>>建议是一个好主意。 – 2010-03-09 00:54:36

+0

未初始化的状态是我不喜欢iostream的原因之一。 – 2010-03-09 01:10:54

+0

相关说明:为什么'int n; istringstream(“5”)>> n;'工作? – Potatoswatter 2010-03-09 01:11:31

相关问题