根据对a previous post的公认答案
声明不是表达式。有些地方表达允许,但不允许声明。 ?的左侧三元运算符,是其中之一。
现在,考虑以下代码段:
#include <iostream>
using std::cout;
using std::endl;
enum struct status{invalid=0, valid};
status test (void);
int main (void){
status s = test();
cout << static_cast<int>(s) << endl;
return (0);
}
status test (void){
static auto invocation_count = 0;
++invocation_count;
//return (invocation_count % 2) ? (status::invalid) : (status::valid);
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
}
函数test()
无法编译(请注意,编译器错误日志在原始测试代码中显示行号):
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In function ‘status test()’:
code.cpp:19:31: error: expected primary-expression before ‘return’
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
^~~~~~
code.cpp:19:31: error: expected ‘)’ before ‘return’
code.cpp:19:83: error: expected ‘:’ before ‘;’ token
(invocation_count % 2) ? (return (status::invalid)) : (return (status::valid));
^
code.cpp:19:83: error: expected primary-expression before ‘;’ token
code.cpp:20:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
make: *** [makefile:20: code.o] Error 1
但是,如果要注释掉错误源test()
中的最后一行,并且启用上面的行(当前已注释掉),则代码将编译。
这两行都使用三元运算符进行返回切换,尽管有所不同。在这两种情况下,三元运算符内?
的左侧均不包含任何声明(实际上,在两种情况下它都是相同的表达式)。
所以为什么一个编译而另一个不编译?
这是合法表达:
{expression}
吗?{expression}
:{expression}
这是法律声明:
返回
{expression}
;
SO:
返回(invocation_count%2)? (状态::无效):(状态::有效);
是:
返回
{expression}
吗?{expression}
:{expression}
;
具有以下格式:
返回
{expression}
;
完全合法。
另一方面,请考虑:
(invocation_count%2)吗? (返回(状态::无效)):(返回(状态::有效));
具有以下形式:
{expression}
吗?{statement}
:{statement}
这是不合法的,因为?:
运算符在冒号之前和之后需要表达式。
三元运算符的部分必须是表达式。 return
不是表达式。这是一个声明。