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

标签 c++ operator-overloading language-lawyer comma-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 , 函数调用的形式是 postfix-expression ( expression-listopt )表达式列表(这是一个 initializer-list ,不要与 std::initializer_list 混淆)是一个 comma separated list of initializer-clauses (假设至少有两个子句)。逗号用于解析表达式列表,它具有特殊含义,而不是表达式的一部分。

索引的形式是后缀表达式 [ 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 ?

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

此外,强制使用逗号非常简单:add parentheses :

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

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

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

关于c++ - 为什么逗号运算符在运算符 [] 中被调用,而不是在运算符 () 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47888273/

相关文章:

c++ - 使用 cin.clear() 之间的区别;

c++ - 尝试将调用对象与另一个对象进行比较时出现段错误

c++ - 如何修复 "There too many argument in this opreator"

c++ - 嵌套类的类内 friend 是否可以访问外部类成员?

通过函数指针的 C++ 函数方法

c++ - 如何权衡精度和速度以评估 C++ 中两个 vector 的点积符号? (不是硬件特定的)

C++11 std::regex Lookbehind 替代方案

c++文件的重载运算符[]

c - 访问二维数组一行末尾的元素是 UB 吗?

c - 使用 union 内的位域来寻址 32 位 `int` 是否是明确定义的行为?