这是三元运算符的合理使用吗?

是否有像代码那样的理解/可维护性问题

inVar1 == 0 ? NULL : v.push_back(inVar1); inVar2 == 0 ? NULL : v.push_back(inVar2); 

等等。

可能令人困惑的想法是使用三元运算符来进行程序流而不是变量赋值,这是通常的解释。

我没有看到解决这种用法的工作中的编码标准,所以虽然我很乐意这样做,但我想知道是否有充分的理由不这样做。

我认为阅读比单纯打字更令人困惑和困难;

 if (inVar != 0) v.push_back(inVar); 

我不得不多次扫描你的例子,以确定结果会有什么确定性。 我甚至更喜欢单行if(){}语句而不是你的例子 – 我讨厌单行if语句:)

三元运算符旨在返回一个值。

IMO,它不应该改变状态,应该使用返回值。

在另一种情况下,使用if语句。 如果语句是为了执行代码块。

三元是一件好事,我通常会提升它的用法。

你在这里所做的事情却玷污了它的可信度。 它更短,是的,但它不必要地复杂化。

我认为应该避免这种情况。 您可以在其位置使用1行if语句。

 if(inVar1 != 0) v.push_back(inVar1); 

这些天的编译器会像三元运算符一样快。

您的目标应该是让其他软件开发人员阅读起来有多容易。

我投票支持

 if ( inVar != 0 ) { v.push_back( inVar ); } 

为什么括号…因为有一天你可能想在那里放一些东西,并且为你预先做了一些括号。 如今,大多数编辑都会把它们放进去。

您使用三元运算符不会获得任何收益,并且会损害代码的可读性。

由于三元运算符返回您未使用的值,因此它是奇数代码。 在像你这样的情况下,使用if更加清晰。

正如评论中提到的那样,这不是有效的C ++ 。 例如,GCC将在此代码上发出错误:

 error: `(&v)->std::vector<_Tp, _Alloc>::push_back [with _Tp = int, _Alloc = std::allocator](((const int&)((const int*)(&inVar1))))' has type `void' and is not a throw-expression 

但是,这可以通过强制转换来解决:

 inVar1 == 0 ? (void)0 : v.push_back(inVar1); inVar2 == 0 ? (void)0 : v.push_back(inVar2); 

但是以什么代价? 为了什么目的?

在这种情况下,这不像使用三元运算符更简洁而不是if语句:

 inVar1 == 0 ? NULL : v.push_back(inVar1); if(inVar1 != 0) v.push_back(inVar1); 

虽然在实践中,我同意那些阻止这种写作的人的观点(在阅读时,你必须做额外的工作来扫描表达的副作用),我想提供

 !inVar1 ?: v.push_back(inVar1); !inVar2 ?: v.push_back(inVar2); 

……如果你想要晦涩难懂,那就是。 GCC允许x ?: y代替x ? x : y x ? x : y 。 🙂

当我需要使用条件参数调用某个函数时,我使用三元运算符 – 在这种情况下, if它更好。

相比:

 printf("%s while executing SQL: %s", is_sql_err() ? "Error" : "Warning", sql_msg()); 

 if (is_sql_err()) printf("Error while executing SQL: %s", sql_msg()); else printf("Warning while executing SQL: %s", sql_msg()); 

我发现前者更具吸引力。 它符合DRY原则,不像后者 – 你不需要写两条几乎相同的线。

我认为你做一个合适的if结构会更好。 我甚至更喜欢总是使用if结构的大括号,如果我必须稍后在条件执行中添加行。

 if (inVar != 0) { v.push_back(inVar); } 

我认为有时候三元组是构造函数的初始化列表中必不可少的恶。 我主要用于构造函数,我想在构造函数的主体之前分配内存并设置一些指向它的指针。

例如,假设您有一个整数存储类,您希望将矢量作为输入,但内部表示是一个数组:

 class foo { public: foo(std::vector input); private: int* array; unsigned int size; }; foo:foo(std::vector input):size(input.size()), array( (input.size()==0)? NULL : new int[input.size]) { //code to copy elements and do other start up goes here } 

这就是我使用三元运算符的方式。 我不认为它像某些人那样令人困惑,但我认为应该限制他们使用它的程度。

我看到的大多数折磨的三元组(如何用于头韵?)仅仅是试图将if语句中真正属于if语句的逻辑放在if语句不属于或不能去的地方。

例如:

 if (inVar1 != 0) v.push_back(inVar1); if (inVar2 != 0) v.push_back(inVar2); 

假设v.push_back是无效的,但是如果它返回一个需要传递给另一个函数的值呢? 在这种情况下,它必须看起来像这样:

 SomeType st; if (inVar1 != 0) st = v.push_back(inVar1); else if (inVar2 != 0) st = v.push_back(inVar2); SomeFunc(st); 

但这更像是为了这么简单的代码而消化。 我的解决方案:定义另一个函数

 SomeType GetST(V v, int inVar1, int inVar2){ if (inVar1 != 0) return v.push_back(inVar1); if (inVar2 != 0) return v.push_back(inVar2); } //elsewhere SomeFunc(GetST(V v, inVar1, inVar2)); 

无论如何,重点在于:如果你有一些逻辑对于三元组而言太过折磨,但是如果把它放在if语句中会使你的代码混乱,那就把它放在其他地方!

 inVar1 != 0 || v.push_back(inVar1); inVar2 != 0 || v.push_back(inVar2); 

在像Perl这样的语言中找到的常见模式。

如果你在一个或两个tenary参数中有多个方法调用,那么它是错误的。 所有代码行都不管什么语句应该简短,理想情况下不是复合的。

正如其他人所提到的,正确的if语句更具可读性。 此外,当您使用调试器单步执行代码时,如果所有内容都在一行中或者您使用的是三元表达式,则无法轻松查看if的哪个分支:

 if (cond) doIt(); cond ? noop() : doIt(); 

以下是更好的步骤(无论你是否有括号):

 if (cond) { doIt(); } 

如上所述,它不比1行if语句更短或更清晰。 然而,它也不再 – 而且并不是那么难以理解。 如果您了解三元运算符,那么很明显发生了什么。

毕竟,如果将其分配给变量(即使它也是变异状态),我认为没有人会遇到问题:

 var2 = inVar1 == 0 ? NULL : v.push_back(inVar1); 

三元运算符总是返回一个值 – IMO – 的事实是无关紧要的。 当然没有要求您使用所有返回值…毕竟,赋值返回一个值。

话虽如此,如果我用NULL分支运行它,我会用if语句替换它。

但是 ,如果它取代了3行if语句:

 if (inVar == 0) { v.doThingOne(1); } else { v.doThingTwo(2); } 

有:

 invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2); 

可能会离开它……取决于我的心情。 ;)