C++将条件运算符中的istream传递给函数
C++ passing istream the in conditional operator to the function
我对条件运算符的行为很困惑。假设函数类似于
SomeData read_from_stream(istream& stream);
函数本身正在返回一些我们想要捕获的数据包。
if (file_name != "")
SomeData data = read_from_stream(ifstream(file_name)); // calling cpy/move constructor
else
SomeData data = read_from_stream(cin);
// data out of scope :(
好的,然后从if-else
中取出SomeData
SomeData data; // calling default constructor :(
if (file_name != "")
data = read_from_stream(ifstream(file_name));
else
data = read_from_stream(cin);
默认构造函数甚至可能不存在。好吧,那就另辟蹊径吧。
SomeData data = read_from_stream((file_name != "") ? ifstream(file_name) : cin);
错误C2248:"std::basic_stream<char,std::char_traits<char>>::basic_stream":无法访问类"std::basic_istream<中声明的受保护成员;char,std::char_traits<字符>>'
嗯,我听说流是不可复制的,但我没有复制任何东西,是吗?
编辑:
我想出了这个
auto lmbd = [&file_name]() -> istream& {
if (file_name != "")
return ifstream(file_name); // returning reference to temporary :(
else
return cin;
};
SomeData data = read_from_stream(lmbd());
这会编译,但如果流是使用文件名设置的ifstream,则在运行时尝试std::getline(stream, str);
时会崩溃。
我听说流是不可复制的,但我没有复制任何东西,是吗?
是的,不幸的是,你是。
在发生任何引用绑定之前,执行从std::ifstream
到std::istream
的转换:
[C++11: 5.16/3]:
[..]如果E2
是右值,或者如果上面的转换都不能完成,并且至少有一个操作数具有(可能是cv限定的)类类型:
- 如果
E1
和E2
具有类类型,并且底层类类型相同,或者其中一个是另一个的基类:如果T2的类与T1
的类类型相同,或其基类,则E1
可以转换为匹配E2
,并且T2
的cv资格与,或者比T1
的cv资格更大的cv资质如果应用转换,则通过从E1
复制初始化T2
类型的临时值并将该临时值用作转换后的操作数,将E1
更改为T2类型的prvalue[..]
有所有的标准方法可以缓解这种情况(其中一些你已经探索过了)。一个真正令人讨厌的方法是向read_from_stream
添加一个重载,该重载接受右值引用,并将两个表达式操作数强制转换为同一类型:
#include <fstream>
#include <iostream>
void f(std::istream&&);
int main()
{
f(
false
? (std::istream&&) std::ifstream("/tmp")
: (std::istream&&) std::cin
);
}
(见编译)
与我的原始代码的测试版本相比:
#include <fstream>
#include <iostream>
void f(std::istream&);
int main()
{
f(
false
? std::ifstream("/tmp")
: std::cin
);
}
("error: use of deleted function 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)'
")
- 使用 istream 参数读取的 istream 函数
- 从函数返回 istream 的正确方法
- C++ 模板类无法修复 ostream 和 istream 函数
- 如何使用 istream::ignore() 函数时检查 EOF 条件
- 为什么COUT在朋友函数中不起作用,该功能超载了操作员&lt;&lt;这是一个iStream运算符
- 在构造函数中从 std::istream 初始化 const 类数据成员
- C++带有 iStream&参数的函数
- 带有 iStream&参数C++的函数
- 将 ifstream 对象传递给需要 istream 类型的函数
- C++将条件运算符中的istream传递给函数
- 使用 istream& 作为函数参数
- 使用 std::istream 运行函数
- 函数int get()和istream&get(char&c)有什么区别
- 在C++中使用非友元方法重载 I/O 运算符 |&istream 和 &ostream 函数
- 如何将 istream 传递给 c++ 中的函数
- C++如何初始化std::istream*,尽管构造函数受到保护
- istream::operator>>( const char& ) 没有这样的函数是如何实现的?
- std::istream子类:删除析构函数中的streambuf
- 如何将std::istream以允许传递临时值的方式传递到函数中
- 带有 istream&as 参数和返回类型的函数C++