为什么逗号运算符在运算符 [] 中被调用,而不是在运算符 () 中?

Why is comma operator called inside operator [] but not inside operator ()?

从前一个问题When all does comma operator not act as a comma operator?,我了解到函数调用中的逗号只能充当表达式分隔符。但是从下面的代码来看,operator() 的行为类似于函数调用,而 operator[] 则不然。

所以我有两个问题:

  1. 为什么逗号运算符在 operator[] 调用中调用而不是在 operator() 调用中调用?
  2. 是否有阻止编译器的特定原因,首先检查 f(a,b) 不匹配任何 f 声明的元数或类型,不会尝试更改逗号状态并查看 f(a.operator,(b)) 导致可接受的语法 ?在我看来,这与类型转换的过程相同。

代码示例:

struct A{ };

struct B {
  A operator,(const B & other) const { return A(); }
};

struct C {
  C(){}
  C(const A & a){}
  void operator[](const A & a) const {}
  void operator()(const A & a) const {}
};

void f(const A & a){}

int main()
{
    B x,y;
    C z;

    //these do no compile because ',' in a function call is an argument separator
    //C(x,y);
    //f(x,y);

    //but this one compiles as z[x.operator,(y)]
    z[x,y];

    //and this one does not
    //z(x,y);

    //finally all of these do compile
    z((x,y));
    C((x,y));
    f((x,y));

   return 0;
}

Why is the comma operator called inside an operator[] call and not inside an operator() call?

如果你看grammatically, function calls are of the form postfix-expression ( expression-listopt ). An expression-list (which is an initializer-list, not to be confused with std::initializer_list) is a comma separated list of initializer-clauses(假设至少有两个子句)。逗号被 表达式列表 的解析所消耗,它具有特殊含义,而不是表达式的一部分。

索引的形式是 postfix-expression [ expr-or-braced-init-list ], 此时没有要消耗的逗号,因此出现的任何逗号都必然是 expression 的一部分。

Is there a specific reason that prevents the compiler, first checking that f(a,b) does not match both the arity or the types of any f declaration, would not try to change the comma status and see if f(a.operator,(b)) leads to an acceptable syntax ?

我将继续 "sanity." 函数调用是程序的一个非常基本的方面,它们需要简单明了。如果您甚至不知道您传递了多少个参数,那将非常容易出错。特别是如果使用内置逗号运算符,它会忽略参数。

另外,强制使用逗号也很简单:add parentheses:

f(a, (t=3, t+2), c);

has three arguments, the second of which has value 5.

这在语法上有效,因为内部逗号不能是分隔 initializer-clauses 的逗号,因为 (t=3 不是 initializer-子句.