[英]Mistake with streaming and conditional operators
最近,我在代码中遇到了一个错误,我认为这可能是一个常见错误。 我已将错误概括为一个错误,并且我想了解为什么它不生成编译器警告或错误。 提前致谢。
错误是以下使用条件运算符和流运算符进行提示:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2;
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 0
// i = 1
我假设第一个打印为0
的数字是false
的数字表示。 我不确定编译器如何解释其余部分。 array[i++]
正在评估,因为i
已经增加了。 这必须是有效的语法,但是完全不需要解释。 还是?
对于那些犯了相同错误但不知道解决方案的人,更正后的代码在条件运算符的周围带有括号:
int i=0;
int array[] = {1};
std::cout << (false ? array[i++] : 2);
std::cout << std::endl << "i = " << i << std::endl;
// output:
// 2
// i = 0
另外,在条件操作之后调用流运算符会生成编译器错误:
int i=0;
int array[] = {1};
std::cout << false ? array[i++] : 2 << std::endl;
std::cout << std::endl << "i = " << i << std::endl;
// fails to compile
// error: invalid operands of types 'int' and '<unresolved overloaded function type>' to binary 'operator<<'
我假设第一个打印为0的数字是false的数字表示。
正确。
我不确定编译器如何解释其余部分。
? :
? :
是三元条件运算符。 第一个子表达式( std::cout << false
)被评估为布尔值,如果为true,则对中间子表达式进行评估( array[i++]
),否则对最后一个子表达式进行评估( 2
)。
std::cout
类型为std::ostream
。 流插入操作符返回流本身。 流具有布尔值的转换运算符(自C ++ 11开始;在转换运算符之前是指向void指针的,在这种情况下,该指针具有相同的行为)。 转换运算符的行为是:
如果流没有错误并且可以进行I / O操作,则返回true。
由于输出流没有错误,因此转换返回true,因此对中间子表达式( array[i++]
)进行求值。
我想了解为什么这不会生成编译器警告或错误。
因为没有错误,并且(毫无疑问)没有警告。 您可能打算写其他东西,但是您写的是一个有效的程序,编译器无法理解您的意图。
请注意,如果您从三元结果中删除了任何副作用: std::cout << false ? array[i] : 2;
std::cout << false ? array[i] : 2;
,那么编译器可能会警告您,因为顶级表达式现在没有副作用了。
如果启用了警告,则PS Clang会警告您的程序:
main.cpp:7:20: warning: operator '?:' has lower precedence than '<<'; '<<' will be evaluated first [-Wparentheses]
std::cout << false ? array[i++] : 2;
~~~~~~~~~~~~~~~~~~ ^
main.cpp:7:20: note: place parentheses around the '<<' expression to silence this warning
std::cout << false ? array[i++] : 2;
^
main.cpp:7:20: note: place parentheses around the '?:' expression to evaluate it first
std::cout << false ? array[i++] : 2;
int i = 0; std::cout << false ? array[i++] : 2;
如果std::cout
没有错误,失败...状态,则std::cout.operator<<(bool)
将转换为布尔值true
。 i++
得到评估,整个语句产生array[0]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.