初始化对istream的引用

abe*_*nky 7 c++ reference

我正在尝试编写我的程序,以便它可以处理StdIn或命令行中指定的文件.

我这样做是通过尝试初始化对a的引用来istream引用cinifstream使用条件.

(此处此处描述类似的技术)

但是当我尝试使用时ifstream,我似乎得到一个错误,即basic_istream move-constructor被声明protected.

istream& refToCIN  ( cin );                      // This is OK
const istream& refToFile = ifstream(args[1]);    // This is OK

const istream& inStream ( FileIsProvided()? ifstream(args[1]) : cin );
// This causes error:
// std::basic_istream<char,std::char_traits<char>>::basic_istream' : 
// cannot access protected member declared in class std::basic_istream<char,std::char_traits<char>>

ProcessStream(inStream); // This could either be a file or cin
Run Code Online (Sandbox Code Playgroud)

这可以通过这种方式合理地完成吗?我有一个很好的选择吗?

Ser*_*eyA 3

您的代码的问题如下:

三元运算符的左侧是临时的(右值)。然而,你的右手边是一个左值(cin是一个左值)。因此,编译器尝试创建临时的cin,并由于复制构造函数不可用而失败。

至于结果 - 您可以简单地将rdbuf()cin 替换为rdbuf()您的文件,并cin在任何地方使用。


这是OP提出的最终解决方案:

ifstream file;
std::streambuf* old_cin_buf = cin.rdbuf(); // Store the old value
if (FileIsProvided())
{
    file.open(args[1]);
    old_cin_buf = cin.rdbuf(file.rdbuf()); // Replace the ReadBuffer on cin.
    // Store the previous value as well.
}
// Use cin for all operations now.  It will either use the File or StdIn as appropriate.
...
// Restore the original value, in case it was changed by using a file.
cin.rdbuf(old_cin_buf); // This is better be done before file object here goes out of scope
Run Code Online (Sandbox Code Playgroud)

  • @abelenky - 编辑原谅:) 不过有一件事 - 你最好在关闭文件之前将 rdbuf 替换回来。 (2认同)