我检查了C ++ 11标准,发现了以下事实:
std::getline(fin, str)
返回basic_ios
个对象,其类具有成员函数explicit operator bool() const;
类basic_ios
没有成员函数operator void*() const;
作为C ++之前的版本。
所以,我认为if (getline(fin, str)) {}
不符合标准。它应该写成
if (bool(getline(fin, str)){}
。 (但是,VC ++ 2012会对此用法发出警告。即强制void *为bool)
我说错了吗?
答案 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
条件下工作的原因。