我遇到了一些有趣的事情,我之前并没有意识到三元运算符(至少在 Visual C++ 98-2010 中)的一些特点。正如 http://msdn.microsoft.com/en-us/library/e4213hs1(VS.71).aspx 所指出的那样,如果表达式和条件表达式都是左值,则结果也是一个左值。
当然,在 c/c++ 中,你通常会写出这样的代码:
int value = (x == 1) ? 1 : 0;
并且从不关心 r-value/l-value 的问题,在这种情况下,1 和 0 都无法转换为左值。
然而,考虑以下代码:
int value = (x == 1) ? y : z;
y 和 z 都是左值,它们或者更准确地说,其中一个是三元运算符的实际结果(而不是其存储值),这可能并不明显(至少我从未深入思考过这个问题)。
但是,这导致我们能够编写以下代码:
(x == 1 ? y : z) = 99;
如果 x == 1,则将 99 赋给 y;否则将 99 赋给 z。
我从未在任何地方看到过这种描述,在所有我读过的关于使用(或通常是否使用)三元运算符的讨论中都没有提到过。
当然,只有在表达式和条件表达式都是左值时才能使用此方法,例如:
(x == 1 ? 0 : z) = 99;
无法编译,因为 0 是一个 r-value,编译器会提示错误。
而且只有在包含括号时才能使用:
x == 1 ? y : z = 99;
这完全是另一回事,如果 (x != 1),则将 99 分配给 z,两边仍然是左值,所以会出现像
这引出了我的问题:
A)这是实际的 c++ 标准的一部分(看起来应该是),而不仅仅是 Microsoft 的东西吗?我已经搜索过但尚未找到相关信息。
B)如果这是众所周知的,并且我一直生活在岩石下面?我从未见过它在任何我记得的代码中使用过,也从未在讨论三元运算符时提到过它。
C)我需要更经常地外出吗?
当然,在 c/c++ 中,你通常会写出这样的代码:
int value = (x == 1) ? 1 : 0;
并且从不关心 r-value/l-value 的问题,在这种情况下,1 和 0 都无法转换为左值。
然而,考虑以下代码:
int value = (x == 1) ? y : z;
y 和 z 都是左值,它们或者更准确地说,其中一个是三元运算符的实际结果(而不是其存储值),这可能并不明显(至少我从未深入思考过这个问题)。
但是,这导致我们能够编写以下代码:
(x == 1 ? y : z) = 99;
如果 x == 1,则将 99 赋给 y;否则将 99 赋给 z。
我从未在任何地方看到过这种描述,在所有我读过的关于使用(或通常是否使用)三元运算符的讨论中都没有提到过。
当然,只有在表达式和条件表达式都是左值时才能使用此方法,例如:
(x == 1 ? 0 : z) = 99;
无法编译,因为 0 是一个 r-value,编译器会提示错误。
而且只有在包含括号时才能使用:
x == 1 ? y : z = 99;
这完全是另一回事,如果 (x != 1),则将 99 分配给 z,两边仍然是左值,所以会出现像
(x == 1 ? y : z = 99) = 100
这样的问题(它根据 x == 1 的真假将 100 分配给 y 或 z,在 x==1 为 false 时覆盖了 z=99 赋值)。这引出了我的问题:
A)这是实际的 c++ 标准的一部分(看起来应该是),而不仅仅是 Microsoft 的东西吗?我已经搜索过但尚未找到相关信息。
B)如果这是众所周知的,并且我一直生活在岩石下面?我从未见过它在任何我记得的代码中使用过,也从未在讨论三元运算符时提到过它。
C)我需要更经常地外出吗?