可能和很多人一样,我输入了这个拼写错误
int a = 0;
cout << a < " "; //note the '<'
但是,MSVC ++编译器仅发出警告
警告C4552:'&lt;' :运算符无效;预期的运营商 副作用
虽然我预计会出现编译错误。它确实是标准的投诉代码吗?是否发生了使代码有效的隐式类型转换或重载?我也很困惑<
运算符是将字符串" "
与整数a
或结果cout << a
进行比较
相关的SO帖子是here。
答案 0 :(得分:7)
<<
运算符的优先级高于<
,因此将其解析为
(cout << a) < " ";
您实际上并不是在将字符串与整数进行比较。相反,您将ostream::operator<<
的返回值(字符{1}}与字符串文字进行比较。这是不合法的(在某种意义上说,它有一个未指明的结果,也没有意义),std::cout
警告:
clang
它编译的原因是直到C ++ 11,warning: result of comparison against a string literal is unspecified
可以隐式转换为std::ostream
。此外,类型为void *
的字符串文字会衰减为类型为const char[2]
的指针。因此,const char *
运算符现在需要两个指针,这是允许的,尽管未指定结果,因为两个指针不指向同一个对象。
答案 1 :(得分:3)
实际上,由于它是(cout << a) < " "
,我们将ostream
与" "
进行比较。 ostream
类有一个运算符可将其转换为void *
。您可以将void *
与const char *
进行比较而不进行强制转换,因此编译器很乐意这样做,然后意识到您没有使用比较结果,并发出警告。
C ++中那些古怪的东西之一。
答案 2 :(得分:1)
归结为运营商precedence
即
该行等于(cout << a) < " ";
- 因此<" "
什么都不做!
修改强>
此位返回一个对象(cout << a)
返回一个类型为ostream
的对象,其中没有重载的运算符<
,因此编译器放弃(C ++ 11)或划伤它的头部amd在整数运算符处有一个bash(即指针等)。