“if(getline(fin,str)){}”是否符合C ++ 11标准?

时间:2013-02-06 03:18:43

标签: c++ c++11 type-conversion iostream explicit-conversion

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

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

  2. basic_ios没有成员函数operator void*() const;作为C ++之前的版本。

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

    if (bool(getline(fin, str)){}。 (但是,VC ++ 2012会对此用法发出警告。即强制void *为bool)

    我说错了吗?

3 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:8)

explicit operator bool(以及 explicit operator bool)具有特殊语言,可以将其隐式转换为某些中的bool情况。此转换的规范语言是“从上下文转换为bool”。

这些是语言进行布尔测试的地方。 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) {...}

答案 2 :(得分:6)

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

  

转换函数可以是显式的(7.1.2),在这种情况下,它只被视为a   用户定义的直接初始化转换(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
}
     

- 结束示例]

发生此上下文转换的某些地方位于!的操作数,&&的操作数和if的条件。

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

  

当且仅当,表达式e可以隐式转换为类型T   对于一些发明的临时声明,T t=e;声明是完整的   变量t(8.5)。 某些语言结构需要一个   表达式转换为布尔值。表达式e出现   在这样的背景下据说是在语境上转换为bool而且是   当且仅当声明bool t(e);格式正确时,格式良好,   对于一些发明的临时变量t(8.5)......

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