这是 ?三元运算合法吗?
Posted
技术标签:
【中文标题】这是 ?三元运算合法吗?【英文标题】:Is this ? ternary operation legal? 【发布时间】:2022-01-17 08:20:03 【问题描述】:我不是专家,但我喜欢学习和理解。考虑到这一点,我在 Arduino IDE 中编写了以下内容:
lockout[idx] ? bulb[idx].off() : bulb[idx].on();
替换这个:
if (lockout[idx]) bulb[idx].off(); else bulb[idx].on();
lockout[]
是 bool
的数组,bulb[]
是一个类的数组,具有 .off
和 .on
方法。
我四处寻找示例,但从未见过?
三元运算符的这种用法。我读到的内容似乎说这不应该起作用。
但它确实可以编译。那么这实际上是合法的 C++ 吗?
【问题讨论】:
只要 off() 和 on() 返回一些东西(不是 void)并且这两个值是兼容的,它就可以工作。通常以某种方式使用三元的输出(例如分配给变量或其他东西)。这不是惯用语。 这并不意味着您应该以这种方式实际使用它。这是丑陋的、具有误导性的,并且可能会在未来产生问题。 @offtkp no?
不只是扩展到if else
。计算返回类型有一些细微的差别,可能会让你措手不及。 C++“扩展”到其他 C++ 的情况很少。我所知道的唯一一个“真正的”是for(:)
循环。其他情况(lambdas,更专业的模板等)在标准中充满了软糖词。同时,?:
不是根据if else
定义的。现在,你说的是一个有用的谎言,但是当你说这些有用的谎言时,你应该尽量弄清楚这一点。
@Offtkp — 这是对 ?:
所做的非常具有误导性的描述。这是一个表达式,所以它有一个值。 if … else …
是一个声明。它没有价值。表达式和语句是根本不同的东西。
除了编译器错误之外,如果 C++ 编译器成功编译,它通常会证明是合法的 C++(尽管它可能具有未定义的行为)。也就是说,如果lockout[idx]
可以转换为数字类型,并且bulb[idx].off()
和bulb[idx].on()
都有效并且返回相同的类型,那么lockout[idx] ? bulb[idx].off() : bulb[idx].on()
绝对是一个有效的表达式。
【参考方案1】:
如果它编译,它可能是格式良好的代码。如果三元运算符由于它们的类型而不能与这些操作数一起使用,编译器将发出错误消息。没有此类错误消息的事实表明您的代码不存在此类问题。
但是,在某些情况下,使用三元运算符可能会导致意外复制。
如果on
和off
方法都返回void
(或者说,bool
),则不会出现任何复制问题,并且代码将按预期工作:如果lockout[idx]
是true 那么bulb[idx].off()
将被评估,否则bulb[idx].on()
将被评估。将只评估两个备选方案中的一个,就像 if
语句会发生的情况一样。
通常,当您需要将结果作为表达式时,会使用三元运算符。否则,使用if
语句编写代码通常更具可读性。
【讨论】:
【参考方案2】:是的,这是合法的 C++。虽然该运算符通常称为 三元运算符,但在 C++ 标准中称为 条件运算符,并在名为“expr.cond”的部分中定义。
C++ 标准明确规定第二个和第三个操作数的类型都可以是void
。因此,标准编写者知道人们可能希望使用此运算符作为编写 if
语句的捷径,就像您正在做的那样。
如果第二个或第三个操作数的类型不是void
,那么标准规定“尝试将这些操作数中的每一个转换为另一个的类型”,并详细说明了这意味着什么。
作为参考,我指的 C++ 标准的版本是 N4296,所以它有点旧,但我认为这并不重要。
【讨论】:
以上是关于这是 ?三元运算合法吗?的主要内容,如果未能解决你的问题,请参考以下文章