在构造函数初始化程序中初始化非const类型时出错?

时间:2015-08-26 09:56:31

标签: c++

错误:

error: invalid initialization of non-const reference of type ‘std::istream& {aka std::basic_istream<char>&}’ from an rvalue of type ‘std::ifstream {aka std::basic_ifstream<char>}’

代码:

class MyClass {
private:
  // why does this need to be a const reference?
  std::istream &fin;
};


MyClass::MyClass(std::string &filename,const char quote, const char sep)
  : fin(std::ifstream(filename)), owns_stream(true), sep(sep), quote(quote)
{
}

如果我将私有fin成员const设置为有效。有人可以解释原因吗?

1 个答案:

答案 0 :(得分:3)

因为您正在初始化临时引用。只有const引用可以做到这一点......虽然它实际上&#34;工作&#34;,因为你有一个悬空引用。引用绑定的这种特殊用法不会延长临时生活

  

[C++14: 12.2/5]: [..] 引用绑定的临时对象或绑定引用的子对象的完整对象的临时对象的生命周期仍然存在参考除外:

     
      
  • 构造函数的 ctor-initializer (12.6.2)中与引用成员的临时绑定将持续存在,直到构造函数退出。
  •   
  • [..]
  •   

执行此操作的传统方法是首先接受构造函数中的流:

MyClass(std::istream& strm, const char quote, const char sep)
  : fin(strm), owns_stream(true), sep(sep), quote(quote)
{}

然后:

std::ifstream ifs("/tmp/something");
MyClass obj(ifs);

这对您的用户来说更加灵活。

否则,如果您希望明确强制使用std::ifstream,只需存储实际的std::ifstream并删除整个临时/参考业务:

class MyClass {
public:
   MyClass(const std::string& filename)
      : fin(filename)
   {}

private:
  std::ifstream fin;
};