【问题标题】:c++ ternary operatorc++ 三元运算符
【发布时间】:2011-03-16 12:10:18
【问题描述】:

所以我遇到了一些我没有意识到的关于三元运算符的有趣事情(至少在 Visual C++ 98-2010 中)。正如http://msdn.microsoft.com/en-us/library/e4213hs1(VS.71).aspx 中所指出的,如果表达式和条件表达式都是左值,则结果是左值。

当然通常在 c/c++ 中你会写这样的东西:

int value = (x == 1) ? 1 : 0;

甚至从不关心右值/左值的参与,在这种情况下,1 和 0 都不能转换为左值。

但是,采取类似的方式:

int value = (x == 1) ? y : z;

y 和 z 都是左值,它们,或者更准确地说,其中一个是三元运算符的实际结果(不是它的存储值),这不一定是显而易见的(至少我从未想过任何长度)。

但是,这导致了编写以下内容的能力

(x == 1 ? y : z) = 99;

如果 x == 1 将 99 分配给 y,如果 x != 1 将 99 分配给 z

在我读过的关于使用(或者,通常是是否使用)三元运算符的所有讨论中,我从未在任何地方和所有讨论中看到过这样的描述。

当然,它只有在表达式和条件表达式都是左值时才有效

(x == 1 ? 0 : z) = 99;

编译失败,因为 0 是编译器高兴地指出的 r 值。

这仅在您包含括号时才有效

x == 1 ? y : z = 99;

是完全不同的东西,仅当 (x != 1) 时才将 99 分配给 z,而美妙的部分是双方仍然是 l 值,所以像 (x == 1 ? y : z = 99) = 100 这样的事情存在严重的鼠洞 (它根据 x == 1 的真值将 100 分配给 y 或 z,如果 x==1 为假,则踩踏 z = 99 分配)

所以,这引出了我的问题:

A) 这是否是实际 c++ 标准的一部分(看起来会是这样),而不仅仅是微软的东西——我已经看过但到目前为止未能找到此信息。

B) 如果这被广泛实现并且我一直生活在一块石头下?我从来没有见过它在我能回忆的任何代码中使用过,也从未见过在讨论三元运算符时提到它。

C) 我需要更频繁地外出吗?

【问题讨论】:

  • A) 是的,根据我模糊的记忆 B) 是的,下面还有更多空间吗? C) 那会有帮助吗?用什么?
  • (B) 当无知是幸福时,聪明是愚蠢的。
  • 您以前没有看过它,因为它很难阅读。难以阅读的代码不利于可维护性。

标签: c++ visual-c++ conditional-operator


【解决方案1】:

A) 是的,这是标准的一部分。

B) 虽然它可能在 SO 上,但它并没有被广泛实现。它被选为 C++ 的 #1 隐藏特性是有原因的:Hidden Features of C++?

C) 没有评论。 :)

就个人而言,我建议不要使用此功能。它比使用if/else 语句要直观得多,而且显然不是每个人都知道它。

违背我自己的警告,我实际上曾在个人项目中尝试过使用它,但由于缺少括号并浪费 30 分钟试图找出错误而被烧毁。

【讨论】:

  • 好吧,我希望我在发布之前就遇到过这个问题:) ...我确实看过,但显然错过了。
【解决方案2】:

答。 是的。 §[expr.cond]/4:

如果第二个和第三个操作数是左值并且具有相同的类型,则结果是该类型并且是左值...

(请注意,它在 C 中不是为真。在 C99 标准脚注 93 中明确写成,“条件表达式不会产生左值。”)

B.我不认为它被广泛使用,因为它的用法非常模糊。比较常见

if (x == 1)
  y = 99;
else
  z = 99;

【讨论】:

  • FWIW:我已经在 Visual 2010 中验证符合脚注 93,因为在尝试编译 @987654322 时会出现编译错误(“...左操作数必须是左值”) @ 在一个 .c (straight-c) 文件中。
【解决方案3】:

您从未见过它被使用过,因为这种用法不如最常见的用法直观和易读。我也从未见过它在生产代码中以这种方式使用过,我希望我永远不会看到它。

记住 Herb Sutter 和 Andrei Alexandrescu 的 C++ Coding Standards,规则 6:“正确、简单和清晰是第一位的。”

【讨论】:

  • 我当然不提倡使用它——目前只是出于好奇
  • @Ruddy:我只是在回答 B。我不确定 A(尽管我 99% 都认为这是真的)还是 C :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 2014-02-08
  • 2023-03-05
  • 2011-02-15
  • 2011-09-30
  • 2021-10-25
相关资源
最近更新 更多