【发布时间】:2017-04-11 06:02:08
【问题描述】:
拿这个玩具代码:
#include <iostream>
#include <fstream>
int main() {
std::ifstream is;
// perform read
// ...
if (!is) // works
std::cout << "fail";
if( is == false) // error C2678
std::cout << "fail";
return 0;
}
你会得到以下违反直觉的结果:if(!is) 编译,if(is==false) 给出
错误 C2678:二进制“==”:未找到采用左手的运算符 'std::ifstream' 类型的操作数(或没有可接受的转换)
(对于 VS2015 - gcc 和 clang 中的类似错误)。
标准说(根据this answer):
依赖于隐式布尔转换的有效 C++ 2003 代码将 不符合本国际标准。此类转换 发生在以下情况:
将值传递给接受 bool 类型参数的函数;
使用 operator== 比较 false 或 true;
从返回类型为 bool 的函数返回值;
通过聚合初始化初始化 bool 类型的成员;
初始化一个 const bool& 将绑定到一个临时对象。
据我所知,if(is==false) 明确要求失败,但为什么 if(!is) 没有?它不符合“隐式布尔转换”的条件吗?
是否有意从标准中列出的案例中省略了这种转换为布尔的情况?也许是无意的遗漏?
编辑: 这段代码也失败了:
int main() {
std::ifstream is;
// perform read
// ...
if (is) // works
std::cout << "success";
if( is == true) // error C2678
std::cout << "success";
return 0;
}
这里操作符的存在!() 是无关紧要的。
【问题讨论】:
标签: c++ c++11 language-lawyer