【问题标题】:When all does comma operator not act as a comma operator?什么时候逗号运算符不充当逗号运算符?
【发布时间】:2011-03-08 21:16:12
【问题描述】:

如果你看到这段代码,

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) 无法编译,因为逗号在这里充当分隔符而不是逗号运算符。

逗号not在哪里可以用作逗号运算符?还是反过来?

【问题讨论】:

    标签: c++ comma-operator


    【解决方案1】:

    从语法的角度来看,函数调用的参数在括号内形成一个可选的表达式列表expression-list 由一个或多个 assignment-expression 组成,由逗号分隔。逗号只能表示需要 表达式 的逗号运算符。

    逗号运算符由一个表达式、一个,和一个赋值表达式组成一个表达式,但是一个涉及逗号运算符的表达式 本身不是 assignment-expression,因此不能出现在 expression-list 中,除非它是某事物的组成部分赋值表达式

    例如,您可以将任何 表达式(包括使用逗号运算符的表达式)括在括号内,以形成一个 primary-expression,它是一个 assignment-expression 因此在 表达式列表 中有效。

    例如

    postfix-expression 其中 expression-list 由两个 assignment-expression 组成,每一个都是一个 identifier.

    f( a, b );
    

    postfix-expression 其中 expression-list 由一个 assignment-expression 组成,它是一个 primary-expression em>,它是一个使用逗号运算符括起来的 表达式

    f( (a, b) );
    

    【讨论】:

      【解决方案2】:

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

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

        例子:

        int a, b;
        
      • parameter-declaration-list 函数参数声明列表(惊喜!)
      • 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】:

        这与表达式的语言定义有关,这是相当复杂的。

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

        【讨论】:

        • 因为这里的逗号是运算符!返回最右边表达式的结果。只是为了澄清任何读者
        【解决方案4】:

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

        至于什么时候是标点符号,简单的答案是“当标准这么说的时候”。经历标准规定的所有情况会给出更长的答案 - 但不太可能更有用,因为(例如)它必须处理大多数人不太关心的一些极端情况关于。

        【讨论】:

          【解决方案5】:

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

          Wikipedia - Comma operator

          【讨论】:

          • 什么是“相似结构”?
          • @Philipp:基本上,语法明确描述逗号含义的那些结构。上面的列表跳过了与变量声明非常相似的实例成员和朋友声明。另一个示例是类似于函数调用的临时对象表达式,例如 Complex(0,1)
          猜你喜欢
          • 1970-01-01
          • 2011-01-13
          • 2010-10-04
          • 2017-07-11
          • 2010-12-16
          • 1970-01-01
          • 2010-09-14
          • 2010-09-08
          相关资源
          最近更新 更多