首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11中的逗号操作符(测序)

C++11中的逗号操作符(测序)
EN

Stack Overflow用户
提问于 2017-09-21 10:13:23
回答 3查看 570关注 0票数 4

根据我的理解,标准提到了f(a,(t=3,t+2),c);,它是一个赋值表达式,后面是第二个运算符的表达式。

但语法列出了它并排的内容:

表达式:

assignment-expression

表达式,赋值表达式

Working Draft, Standard for Programming Language C ++ Revision N4140 (November 2014)

有人能给我解释一下我在这里失踪的原因吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-21 10:48:14

当你看到

表达式:赋值-表达式表达式,赋值表达式

这意味着有两种表达的可能性。一种可能性是,在前面某个地方定义的仅仅是assignment-expression。或者递归表示为expression, assignment-expression

因此,在扩展它之后,您将收到一个或多个赋值表达式标记的逗号分隔列表。

在示例中,我们提到了第二个参数是表达式(t=3,t+2),它由两个逗号分隔的赋值表达式组成,并且由于它出现在“在逗号被赋予特殊意义的上下文中”,所以它必须“只出现在括号中”。

要了解为什么赋值表达式可以采用t+2的形式,您必须从它的定义中返回并始终选择第一选择。

代码语言:javascript
复制
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
票数 9
EN

Stack Overflow用户

发布于 2017-09-21 10:57:53

注意,因为表达式的定义是

表达方式: 赋值-表达式 表达式,分配-表达式

第二行意味着任何赋值表达式都可以被视为表达式,这就是为什么t=3, t+2是一个有效表达式的原因。

为什么语法是这样的呢?首先,请注意,表达式的语法按步骤构建,从绑定最紧密的类别主表达式到绑定最紧的类别表达式。(然后,"( expression )“是一个主表达式这一事实使表达式语法完整,并允许我们通过添加括号使任何表达式比围绕它的所有表达式都更加紧密地绑定。)

例如,二进制*比二进制+绑定更紧密这一众所周知的事实来自于以下语法片段:

乘法-表达: pm-表达式 乘法-表达式* pm-表达式 乘法-表达式/ pm-表达式 乘法-表达式% pm-表达式 加性-表达: 乘法表达式 加性表达式+乘法表达式 加性表达式-乘法表达式

在表达式2 + 3 * 4中,文字234可以被认为是pm表达式,因此也可以被认为是乘法表达式或加性表达式。所以你可能会说2 + 3是一个加性表达式,但它不是乘法表达式,所以完整的2 + 3 * 4不能那样工作。相反,语法迫使3 * 4被认为是一个乘法表达式,因此2 + 3 * 4可以是一个加式表达式。因此,3 * 4是二进制+的子表达式。

或者在表达式2 * 3 + 4中,3 + 4可能被认为是一个加性表达式,但是它不是pm-表达式,所以这是行不通的。相反,解析器必须认识到2 * 3是一个乘法表达式,它也是一个加性表达式,因此2 * 3 + 4是一个有效的加性表达式,2 * 3是二进制+的子表达式。

当同一个操作符被使用两次或两个优先级相同的操作符被使用时,大多数语法定义的递归性质很重要。

回到逗号语法,如果我们有标记"a, b, c",我们可以说b, c可以是表达式,但它不是赋值表达式,因此b, c不能是整体的子表达式。相反,语法要求将a, b识别为表达式,该表达式允许作为另一个逗号运算符的左子表达式,因此a, b, c也是一个以a, b作为左操作数的表达式。

这对内置逗号没有任何影响,因为它的含义是关联的:“评估和丢弃a,然后结果值来自于评估(评估和丢弃b,然后结果值来自评估c)”与“评估和丢弃(评估和丢弃a,然后结果值来自评估b)”一样,结果值来自于评估c

但它确实给了我们一个明确定义的行为,在operator,超载的情况下。给予:

代码语言:javascript
复制
struct X {};
X operator,(X, X);
X a, b, c;
X d = (a, b, c);

我们知道最后一行意味着

代码语言:javascript
复制
X d = operator,(operator,(a,b), c);

而不是

代码语言:javascript
复制
X d = operator,(a, operator,(b,c));

(我认为定义一个非关联的operator,是特别邪恶的,但它是允许的。)

票数 5
EN

Stack Overflow用户

发布于 2017-09-21 10:51:53

代码语言:javascript
复制
 f(a,(t=3,t+2),c);

这里,首先将3存储到t变量中,然后使用三个参数调用函数f()。这意味着第二个参数值变成5并传递给函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46341225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档