标准提到 f(a,(t = 3,t + 2),c); 根据我的理解,它将是赋值表达式,后跟第二个运算符的表达式。
但语法列出并列:
表达式:
赋值表达式
表达式,赋值表达式
Working Draft, Standard for Programming Language C ++ Revision N4140 (November 2014)
有人如此高兴向我解释我在这里失踪的是什么吗?
答案 0 :(得分:8)
当你看到
expression: assignment-expression expression, assignment-expression
这意味着表达有两种可能性。只有 assignment-expression
才有可能在之前的某处定义。或者以递归方式表示为 expression, assignment-expression
因此,在扩展它之后,您会收到该表达式是一个或多个赋值表达式标记的逗号分隔列表。
在示例中,您提到第二个参数是表达式(t = 3,t + 2),它由2个以逗号分隔的赋值表达式组成 - 并且因为它出现"在给出逗号的上下文中特殊含义"它必须只出现在括号中#34;。
要找出为什么赋值表达式可以采用t + 2的形式,你必须从它的定义返回并始终选择第一选择
assignment-expression
-> conditional-expression
--> logical-or-expression
---> logical-and-expression
----> inclusive-or-expression
-----> exclusive-or-expression
------> and-expression
-------> equality-expression
--------> relational-expression
---------> shift-expression
----------> additive-expression - this is what you see
答案 1 :(得分:2)
这是语法表示法(参见N4140的§1.6)。
它主要用于评估优先级,但名称可能会产生误导。
例如在[expr.ass](§5.18)中,您有以下定义:
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ^= |=
即使两项任务都没有执行任务,assignment-expression
也可以是conditional-expression
或throw-expression
。
这只是说明a = b
,throw 10
或cond ? c : d
是具有相同优先顺序的表达式。
答案 2 :(得分:1)
请注意,由于表达式的定义是
表达:
assignment-expression
表达式
,
assignment-expression
第二行表示任何赋值表达式都可以被视为表达式,这就是t=3, t+2
是有效表达式的原因。
那么为什么语法会这样呢?首先请注意,表达式的语法从最紧密绑定的类别 primary-expression 到最紧密绑定的类别表达式逐步构建。 (然后“(
表达式 )
”是 primary-expression 的事实使表达式语法完整循环并让我们引起任何表达通过添加括号,比围绕它的所有东西更紧密。)
例如,众所周知的事实是二进制*
比二进制+
更紧密地遵循这些语法部分:
乘法表达:
pm-expression
multiplicative-expression
*
pm-expressionmultiplicative-expression
/
pm-expressionmultiplicative-expression
%
pm-expression添加剂的表达:
multiplicative-expression
additive-expression
+
multiplicative-expressionadditive-expression
-
multiplicative-expression
在表达式2 + 3 * 4
中,文字2
,3
和4
可以被视为 pm-expression ,或者也可以乘法表达式或加法表达式。所以你可能会说2 + 3
符合 additive-expression 的条件,但它不 multiplicative-expression ,所以完整2 + 3 * 4
无法以这种方式工作。相反,语法强制3 * 4
被视为乘法表达式,因此2 + 3 * 4
可以是添加表达式。因此,3 * 4
是二进制+
的子表达式。
或者在表达式2 * 3 + 4
中,3 + 4
可能会被视为 additive-expression ,但它不是 pm-expression ,所以这不起作用。相反,解析器必须识别2 * 3
是乘法表达式,它也是加法表达式,因此2 * 3 + 4
是有效的 additive-expression ,2 * 3
作为二进制+
的子表达式。
当使用两次相同的运算符或使用两个具有相同优先级的运算符时,大多数语法定义的递归性质很重要。
回到逗号语法,如果我们有令牌“a, b, c
”,我们可能会说b, c
可能是表达式,但它不是 assignment-expression ,因此b, c
不能是整体的子表达式。相反,语法要求将a, b
识别为表达式,允许将其作为另一个逗号运算符的左子表达式,因此a, b, c
也是表达式以a, b
作为左操作数。
这对内置逗号没有任何影响,因为它的含义是关联的:“评估并放弃a
,然后结果值来自评估(评估和丢弃b
,然后结果值来自评估c
)“与”评估和丢弃(评估并丢弃a
,然后结果值来自评估b
),然后结果值“相同来自评估c
“。
但是在重载operator,
的情况下,它确实为我们提供了明确定义的行为。给出:
struct X {};
X operator,(X, X);
X a, b, c;
X d = (a, b, c);
我们知道最后一行意味着
X d = operator,(operator,(a,b), c);
而不是
X d = operator,(a, operator,(b,c));
(我认为定义一个非关联operator,
特别邪恶,但允许它。)
答案 3 :(得分:0)
f(a,(t=3,t+2),c);
首先,将3
存储到t
变量中,然后使用三个参数调用函数f()
。这意味着第二个参数值变为5
并传递给函数。