初始化对istream的引用
我正在尝试编写我的程序,以便它可以处理StdIn或在命令行中指定的文件。
我通过尝试初始化一个istream
的引用来引用cin
或ifstream
,使用条件来做到这一点。
(类似的技术在这里和这里描述)
但是,当我尝试使用ifstream
,我似乎得到一个错误,即basic_istream移动构造函数被声明为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
这可以通过这种方式合理地完成吗? 我忽略了一个很好的选择吗?
你的代码的问题如下:
三元运算符的左侧是一个临时(右值)。 然而,你的右手边是一个左值( cin
是左值)。 因此,编译器试图从cin
创建一个临时文件,并且因为复制构造函数不可用而失败。
至于sultions -你可以简单地替换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
这听起来像一个XY问题,因为你不需要这里的三元条件或参考。
作为惯例,许多程序使用-
表示stdin
而不是省略文件名。 这是一条可能的途径。 根据类似的思路,我会使用Boost.ProgramOptions或getopt
代替手动解析命令行。 这将间接地解决您的XY问题,因为它会使FileIsProvided()
函数变得冗余,并且您将通过除直接使用argv[1]
之外的其他方法获得您的选项。
如果你有C ++ 11,有智能指针或std::reference_wrapper
,它允许你“重置”引用。
作为一个反动力,考虑像ostream_joiner
这样的类保持一个指向其内部流对象的指针,而不是引用。 另外,我怀疑你是否喜欢不必看处理来自无害代码的悬挂引用。
除此以外...
if (FileIsProvided())
{
std::ifstream ifs(argv[1]);
if (ifs)
{
ProcessStream(ifs);
}
} else {
ProcessStream(std::cin);
}
链接地址: http://www.djcxy.com/p/91939.html