acr*_*075 11 c++ type-conversion visual-c++ language-lawyer c++11
以下代码在Visual Studio 2008中编译,但在Visual Studio 2013及更高版本中失败.
std::string str("foo");
std::stringstream ss(str);
float f = 0;
if ((ss >> f) == false)
std::cout << "Parse error\n";
Run Code Online (Sandbox Code Playgroud)
错误消息是
错误C2678:二进制'==':找不到哪个运算符带有'std :: basic_istream>'类型的左操作数(或者没有可接受的转换)
并通过以下更改成功修复:
if (!(ss >> f))
std::cout << "Parse error\n";
Run Code Online (Sandbox Code Playgroud)
我不太了解这一点.我的问题是,ios涉及哪些运算符或强制转换或可能是 标志,允许流读取首先被评估为布尔值,然后为什么缺少一个operator==中断呢?
son*_*yao 16
自C++ 11以来,两种行为发生了变化
std :: basic_ios :: operator bool的行为发生了变化.
operator void*() const; (1) (until C++11)
explicit operator bool() const; (2) (since C++11)
Run Code Online (Sandbox Code Playgroud)
注意,因为C++ 11 operator bool()被声明为explicit; 但对于if ((ss >> f) == false),ss(即返回值(ss >> f))需要是隐式转换为bool(与相比false),这是不允许的.
空指针常量的定义已更改.
在使用C++ 11之前operator void*()并没有explicit(在C++ 11之前没有这种显式的用户定义转换),在C++ 11之前,空指针常量定义为:
整数类型的整数常量表达式rvalue,其计算结果为零(直到C++ 11)
这意味着false可以用作空指针常量.因此ss可以隐式转换为void*然后与false(与空指针)进行比较.
从C++ 11开始,空指针常量定义为:
一个值为零的整数文字,或者是一个类型的prvalue
std::nullptr_t(从C++ 11开始)
而false不是再次; 它不是整数文字.
因此,由于这两个更改,if ((ss >> f) == false)将无法在C++ 11及更高版本中使用.
另一方面,if (!(ss >> f))工作正常,因为有std :: basic_ios :: operator!(对于它来说,在C++ 11之前和之后).
Run Code Online (Sandbox Code Playgroud)bool operator!() const;
true如果关联的流上发生错误,则返回.具体来说,true如果设置了badbit或failbit ,则返回rdstate().
顺便说一句:由于C++ 11,即使没有std::basic_ios::operator!,explicit operator bool() const也可以if (!(ss >> f))很好地工作,因为在上下文转换的上下文中,explicit考虑了用户定义的转换; 即ss可以在上下文中转换bool为operators !.
| 归档时间: |
|
| 查看次数: |
887 次 |
| 最近记录: |