为什么我不能将std::getline的仿布尔结果返回?

33
一项标准的习语是:

A standard idiom is

while(std::getline(ifstream, str))
    ...

所以如果那样可行,为什么我不能这么说呢?

bool getval(std::string &val)
{
    ...

    std::ifstream infile(filename);

    ...

    return std::getline(infile, val);
}

g++显示:“cannot convert 'std::basic_istream<char>' to 'bool' in return”。

在返回布尔值的函数中,return语句的布尔上下文是否与while()的布尔上下文有所不同,以至于std::basic_istream在一个上下文中执行的魔法转换在另一个上下文中无法工作?


补充说明:这似乎与某些版本和可能的语言标准有关。我在使用g++ 8.3.0时遇到了上述错误。但是我没有在gcc 4.6.3或LLVM(clang)9.0.0中遇到此问题。


嗯,强制转换可以工作,但隐式转换不行——翻页 C++ 5 级巫师。 - pm100
return !!std::getline(infile, val); 可以作为一个选项。 - Ted Lyngmo
3
很少有问题像这个一样引起我的兴趣,不错。我期待着看到答案,因为编译器拥有所有必要的信息来知道它必须以布尔值结束。 - paxdiablo
OT: @TedLyngmo 嗯,也许更好的做法是使用更“明确”的方式:return std::getline(infile, val).good(); - Bob__
1个回答

49

std::basic_istream的布尔类型转换运算符是explicit的。这意味着该类型的实例不会隐式地成为一个bool类型,但可以通过显式转换变为一个bool类型,例如输入bool(infile)

显式的布尔类型转换运算符通常用于条件语句中,例如ifwhile等表达式部分。有关情境转换的更多信息,请点击此处

然而,在return语句中,不会考虑explicit的类型转换运算符或构造函数。因此,您必须显式地将其转换为布尔类型才能进行return操作。


19
所以,“显式”的转换有时并不是最好的选择。 - pm100
2
谢谢。explicit是那些递减回报细微差别之一,我的老脑袋认为它不重要,但在我的std::getline()调用周围加上bool(...)似乎很有效。 - Steve Summit
3
“当初始化一个T2类型的新对象时,在返回T2类型的函数中包含返回语句” - 这在文档中有提到,为什么这里不适用呢? - paxdiablo
2
没关系,我刚刚按照你提供的链接进行了上下文转换。我找到的资料似乎只说明了隐式转换发生的位置,而没有说明哪些地方不能进行显式转换。你提供的另一个链接澄清了这一区别。回答得很好。 - paxdiablo
6
在这种情况下,!的操作数被视为将其显式转化为布尔值,但由于istream已经实现了operator!,因此需要注意。 - Remy Lebeau
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接