Vin*_*nod 1 c++ return ternary-operator
根据上一个帖子的公认答案
声明不是表达式。在某些地方允许使用表达式,但不允许使用声明。三元运算符?的左侧是其中之一。
现在,考虑以下代码段:
#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));
}
Run Code Online (Sandbox Code Playgroud)
该函数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
Run Code Online (Sandbox Code Playgroud)
但是,如果test()要注释掉其中的最后一行(这是错误的来源),并且要启用上面的行(当前已注释掉),则代码将编译。
两条线都使用三元运算符进行返回切换,尽管有所不同。而且在这两种情况下,?三元运算符内部的左侧都不包含任何声明(实际上,在两种情况下它都是相同的表达式)。
那么,为什么一个编译而另一个则不编译呢?
这是一个法律表达:
{expression}?{expression}:{expression}
这是法律声明:
回报
{expression};
所以:
返回(invocation_count%2)?(状态::无效):(状态::有效);
是:
回报
{expression}?{expression}:{expression};
形式如下:
回报
{expression};
那是完全合法的。
另一方面,请考虑:
(invocation_count%2)?(返回(状态::无效)):(返回(状态::有效));
其形式为:
{expression}?{statement}:{statement}
这是不合法的,因为?:运算符在冒号之前和之后都需要表达式。