我刚刚遇到以下(匿名)C++ 代码:
auto my_flag = x > threshold;
my_flag ? do_this() : do_that();
这是一个标准的 C++ 习惯用法,而不是使用 if-else:
if (x > threshold)
{
do_this();
}
else
{
do_that();
}
即使只有两行,我也必须回去重新阅读它以确保我知道它在做什么。
标记的重复项没有像此处选择的那样好的答案。如果可以与重复项合并,我想将此答案保留在“重复项”上的其他答案之上。
另请注意,我的问题是关于“习语”的。另一个是“合法性”。编译器说“合法”没问题。
不。一般来说,条件运算符不能替代
if-else
。
最显着的区别是条件运算符的最后两个操作数需要具有共同的类型。您的代码无法使用,例如:
std::string do_this() {return {};}
void do_that() {}
会出现错误,因为
void
和std::string
没有共同类型:
<source>: In function 'int main()':
<source>:15:22: error: third operand to the conditional operator is of type 'void', but the second operand is neither a throw-expression nor of type 'void'
15 | my_flag ? do_this() : do_that();
| ~~~~~~~^~
此外,条件运算符通常可读性较差。
条件运算符可用于复杂的内联初始化。例如你不能写:
int x = 0;
int y = 0;
bool condition = true;
int& ref; // error: must initialize reference
if (condition) ref = x; else ref = y; // and even then, this wouldn't to the right thing
但是你可以写
int& ref = condition ? x : y;
我的建议是,与
if-else
相比,不要使用条件运算符来节省一些击键。它并不总是等价的。
PS:该运算符称为“条件运算符”。术语“三元运算符”更通用,例如一元或二元运算符。 C++ 恰好只有一个三元运算符(即条件运算符)。
它们确实大致相同。请注意,对于三元条件运算符,两个分支需要具有足够相关的类型,以便可以为整个表达式 1 估算公共类型。如果您的用户定义类型带有具有副作用的转换运算符,您可以设计出完全不同的三元条件运算符的行为:
#include <iostream>
struct do_this
{
operator int() const
{
std::cout << "Pay me a bonus";
return 0;
}
};
struct do_that
{
operator int() const
{
std::cout << "Reformat my hard disk";
return 0;
}
};
int main()
{
true ? do_this() : do_that();
}
因此,如果不需要三元条件的结果,应该认为
if
块更清晰。
1参考:https://en.cppreference.com/w/cpp/language/operator_other
if-then 和三元条件最大的区别在于意图:
所以:
if (want_to_do_this) {
do_this();
} else {
do_that();
}
int result = want_to_get_this? get_this(): get_that();
int my_int_max(int i1, int i2) { return i1 > i2? i1: i2; }
我认为这是普遍预期的,但我在已经给出的答案中没有看到这一点。
不,它不是 if-else 的标准替代品
但是,是的,它工作得很好。
例如我有这个示例 C++ 代码
#include <iostream>
using namespace std;
void test1(){
cout<< "test 1"<<endl;
}
void test2(){
cout<< "test 2"<<endl;
}
int main() {
1>2?test1():test2();
}
这是输出
test 2
这和这样做是一样的
#include <iostream>
using namespace std;
void test1(){
cout<< "test 1"<<endl;
}
void test2(){
cout<< "test 2"<<endl;
}
int main() {
if(1>2){
test1();
}else{
test2();
}
}
但是使用 if-else 块使得它更容易阅读,尽管它使它有点长。