gpt4 book ai didi

C++ 将 istream in 条件运算符传递给函数

转载 作者:行者123 更新时间:2023-11-28 06:20:34 24 4
gpt4 key购买 nike

我对条件运算符的行为很困惑。假设函数是这样的

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 :(

好吧,把 SomeData 放在 if-else

之外
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);

error C2248: '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>>'

好吧,我听说流是不可复制的,但我没有复制任何东西,是吗?

编辑:

我想出了这个

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());

这会编译,但在尝试 std::getline(stream, str); 如果流是使用文件名设置的 ifstream 时,它会在运行时崩溃。

最佳答案

I've heard something about streams being not-copyable, but I am not copying anything, am I?

是的,不幸的是,你是。

std::ifstream 执行转换至 std::istream在任何引用绑定(bind)发生之前:

[C++11: 5.16/3]: [..] If E2 is an rvalue or if neither of the conversions above can be done and at least one of the operands has (possibly cv-qualified) class type:

  • if E1 and E2 have class type, and the underlying class types are the same or one is a base class of the other: E1 can be converted to match E2 if the class of T2 is the same type as, or a base class of, the class of T1, and the cv-qualification of T2 is the same cv-qualification as, or a greater cv-qualification than, the cv-qualification of T1. If the conversion is applied, E1 is changed to a prvalue of type T2 by copy-initializing a temporary of type T2 from E1 and using that temporary as the converted operand.

[..]

有所有标准方法可以缓解这种情况(您已经探索过其中一些方法)。一个非常讨厌的工作是向 read_from_stream 添加一个重载。它采用右值引用,并将两个表达式操作数转换为相同的类型:

#include <fstream>
#include <iostream>

void f(std::istream&&);

int main()
{
f(
false
? (std::istream&&) std::ifstream("/tmp")
: (std::istream&&) std::cin
);
}

( see it compiling )

与我的原始代码的测试用例版本相比:

#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>&)' " )

关于C++ 将 istream in 条件运算符传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29371463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com