7

我检查了 C++11 标准,发现以下事实:

  1. std::getline(fin, str)返回一个basic_ios对象,其类有一个成员函数explicit operator bool() const;

  2. 该类basic_ios没有operator void*() const;C++11 之前的成员函数。

所以,我认为if (getline(fin, str)) {}不符合标准。它应该写成

if (bool(getline(fin, str)){}. (但是,VC++ 2012 对这种用法给出了警告。即强制 void* 为 bool)

我对么?

4

3 回答 3

12

代码符合要求。bool当对象被自动用作条件时,将调用显式转换运算符 to 。标准的更改旨在保持相同的用法,同时使其更安全。

于 2013-02-06T03:20:23.337 回答
8

explicit operator bool(并且只有 explicit operator bool)具有允许它bool某些情况下隐式转换为 a 的特殊语言。此转换的规范语言是“上下文转换为bool”。

这些是语言进行布尔测试的地方。an 使用的条件表达式if/while/for是“上下文转换为bool”。逻辑运算符和条件运算符 ( ?:) 也是如此。

所以虽然你不能这样做:

bool b = std::getline(fin, str);
void func(bool) {}
func(std::getline(fin, str));

你可以这样做:

while(std::getline(fin, str)) {...}
for(;std::getline(fin, str);) {...}
if(std::getline(fin, str) && somethingElse) {...}
于 2013-02-06T04:21:06.523 回答
6

大卫是正确的,这里有支持他的引述。在 §12.3.2/2 中,标准说

转换函数可能是显式的(7.1.2),在这种情况下,它仅被视为直接初始化的用户定义转换(8.5)。否则,用户定义的转换不限于在赋值和初始化中使用。[示例

class Y { };
struct Z {
    explicit operator Y() const;
};

void h(Z z) {
    Y y1(z); // OK: direct-initialization
    Y y2 = z; // ill-formed: copy-initialization
    Y y3 = (Y)z; // OK: cast notation
}

结束示例]

发生这种上下文转换的一些地方是在操作数 to !、操作数 to&&和条件 a 中if

因此直接初始化可以使用显式转换运算符,并且在 §4/3 中,

对于某些发明的临时变量 t (8.5),T当且仅当声明格式正确时,表达式 e 才能隐式转换为类型。某些语言结构要求将表达式转换为布尔值。出现在这种上下文中的表达式 e 被称为在上下文中转换为 bool 并且当且仅当声明格式正确时,对于某些发明的临时变量(8.5)...T t=e;bool t(e);t

如您所见,该标准为上下文转换指定了好像直接初始化,这就是显式转换在if条件下工作的原因。

于 2013-02-06T04:20:35.903 回答