运算符优先级更改

时间:2014-07-28 16:11:17

标签: c++ visual-studio-2008 visual-studio-2013

以下用于在VS2008上构建OK,但在VS2013上,它呻吟。好的,用g ++。

#include <sstream>
int main()
{
    int a = 2, b = 5;
    std::ostringstream oss;

    oss << a == 0 ? a : b;
}

错误消息是

1>u:\precedence\precedence.cpp(7): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_ostream<char,std::char_traits<char>>' (or there is no acceptable conversion)
1>          c:\program files\microsoft visual studio 12.0\vc\include\exception(497): could be 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &)' [found using argument-dependent lookup]
1>          c:\program files\microsoft visual studio 12.0\vc\include\exception(502): or       'bool std::operator ==(std::nullptr_t,const std::exception_ptr &)' [found using argument-dependent lookup]
1>          c:\program files\microsoft visual studio 12.0\vc\include\exception(507): or       'bool std::operator ==(const std::exception_ptr &,std::nullptr_t)' [found using argument-dependent lookup]
1>          c:\program files\microsoft visual studio 12.0\vc\include\system_error(402): or       'bool std::operator ==(const std::error_code &,const std::error_condition &) throw()' [found using argument-dependent lookup]
1>          c:\program files\microsoft visual studio 12.0\vc\include\system_error(410): or       'bool std::operator ==(const std::error_condition &,const std::error_code &) throw()' [found using argument-dependent lookup]
1>          while trying to match the argument list '(std::basic_ostream<char,std::char_traits<char>>, int)'

如果输出语句更改为

,它适用于两个版本
    oss << (a == 0? a: b);

如果不使用常量,我可以在VS2008中强制执行不同的错误:类似

int zero = 0;
oss << a == zero? a: b;

只是想知道为什么在没有使用常量时会出现错误。

编辑管理以使用-Wall获得g ++警告。

2 个答案:

答案 0 :(得分:7)

由于优先级,编译器看到的表达式在所有情况下都是:

((oss << a) == 0) ? a : b;

现在oss << a会返回oss。你如何比较oss和0?它有一个隐式转换运算符operator void *

VS2013可能用explicit operator bool取代了C ++ 11(其中的重点是这些难以发现的错误不会发生)。根据我的知识,libstdc ++还没有完成这个替换。它必须符合C ++ 11。

为什么不编译zerozero不是空指针常量,但0是。因此,后者可以与operator void *返回的指针进行比较。

在任何情况下,修复此问题的简单方法是使其适用于任何符合要求的实现,即添加括号:

oss << (a == 0 ? a : b);

答案 1 :(得分:2)

看起来编译器正在解释它不同。

根据错误,我怀疑编译器正在解释像这样的代码行

(oss << a) == 0 ? a : b;

所以,当你放入parens时,它不再能以任何方式解释它,并且你得到了预期的结果。 我怀疑这也会奏效。

oss << (a == 0) ? a : b;