当所有逗号运算符都不作为逗号运算符时?

时间:2010-06-27 18:20:22

标签: c++ comma-operator

如果您看到此代码,

class A{
public:
    A(int a):var(a){}
    int var;
};

int f(A obj) {
    return obj.var;
}

int main() {
    //std::cout<<f(23);    // output: 23
    std::cout<<f(23, 23);  // error: too many arguments to function 'int f(A)'
    return 0;
}

f(23, 23)无法编译,因为逗号在此处充当分隔符,而不是逗号运算符。

逗号的所有内容都以逗号运算符的形式运行?或者反过来?

5 个答案:

答案 0 :(得分:11)

从语法的角度来看,函数调用的参数在括号内形成一个可选的表达式列表表达式列表由一个或多个由逗号标记分隔的赋值表达式组成。逗号只能表示期望表达式的逗号运算符。

逗号运算符从表达式,赋值表达式中创建表达式,但是<涉及逗号运算符的em> expression 本身不是赋值表达式,因此不能出现在表达式列表中,除非它是某个成分的组成部分是赋值表达式

例如,您可以在 primary-expression 赋值表达式)中将括号内的任何表达式(包括使用逗号运算符的表达式)包围起来因此在表达式列表中有效。

E.g。

postfix-expression 其中表达式列表由两个赋值表达式组成,每个赋值表达式标识符

f( a, b );

postfix-expression 其中表达式列表包含一个赋值表达式,它是 primary-expression 是使用逗号运算符的带括号的表达式

f( (a, b) );

答案 1 :(得分:8)

  

使用逗号标记作为   运算符与其使用不同   函数调用和定义,   变量声明,枚举   声明和类似的结构,   它充当分隔符。

Wikipedia - Comma operator

答案 2 :(得分:8)

我搜索了标准草案。基本上,在语法中,-list制作是用逗号分隔不同的项目的制作。以下结果是C ++ 03特有的。在C ++ 0x中, expression-list 直接委托给 initializer-list ,因为在C ++中,0x括号列表同样可以出现在函数和构造函数参数中。

  • 表达式列表对于函数/构造函数参数(包括功能强制转换)
  • 枚举器列表 枚举的项目列表
  • init-declarator-list 在一个声明中声明的不同名称

    示例:

    int a, b;
    
  • 参数声明列表 功能的参数声明列表(惊喜!)
  • initializer-list 类似于表达式列表的列表,但可以包含支撑表达式列表。用于聚合初始化(初始化数组或结构)
  • member-declarator-list 与init声明者列表类似,但对于类中的成员声明

    示例:

    struct A { int a, b; };
    
  • base-specifier-list 类的基类列表。
  • mem-initializer-list 成员的初始值设定项列表

    示例:

    struct A { A():a(0), b(0) { } int a; int b; };
    
  • template-parameter-list 模板参数声明的列表。
  • template-argument-list 传递给模板的模板参数列表。
  • type-id-list 例外规范的类型列表

    示例:

    void f() throw(int, bool) { }
    

宏参数也有一个标识符列表,我没有进入该列表,因为它实际上是预处理器语法的一部分。

答案 3 :(得分:7)

这与表达式的语言定义有关,这非常复杂。

f(1, 2)是一个带有两个参数的函数调用表达式。相反,f((1, 2))是一个带有一个参数的函数调用表达式,它是子表达式1, 2,它将计算为2。

答案 4 :(得分:1)

逗号运算符始终充当逗号运算符,但逗号并不总是表示逗号运算符 - 有时它只是标点符号。

关于它的标点符号,简单的答案就是“当标准这样说时”。经历标准所说的所有情况都会给出更长的答案 - 但是这个问题不太可能有用,因为(例如)它必须处理大多数人不关心的大量案例约。