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

问题描述 投票:9回答:1

从前一个问题When all does comma operator not act as a comma operator?,我明白函数调用中的逗号只能充当表达式sperator。但是从下面的代码中可以看出,operator()的行为类似于函数调用,而operator[]却没有。

所以我有两个问题:

  1. 为什么逗号运算符在operator[]调用内调用而不是在operator()调用内?
  2. 是否存在阻止编译器的特定原因,首先检查f(a,b)是否与任何f声明的arity或类型都不匹配,不会尝试更改逗号状态并查看f(a.operator,(b))是否导致可接受的synthax?从我的角度来看,它将与类型转换相同。

代码示例:

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;
}
c++ operator-overloading language-lawyer comma
1个回答
9
投票

为什么逗号运算符在operator[]调用内调用而不是在operator()调用内?

如果你看grammatically,函数调用的形式为postfix-expression ( expression-listopt )。表达式列表(这是一个initializer-list,不要与std::initializer_list混淆)是comma separated list of initializer-clauses(假设至少有两个条款)。逗号由表达式列表的解析消耗,它具有特殊含义,而不是表达式的一部分。

索引的形式为postfix-expression [ expr-or-braced-init-list ],此时不会使用逗号,因此出现的任何逗号都必然是expression的一部分。

是否存在阻止编译器的特定原因,首先检查f(a,b)是否与任何f声明的arity或类型不匹配,不会尝试更改逗号状态并查看f(a.operator,(b))是否导致可接受的语法?

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

而且,强制使用逗号是非常简单的:add parentheses

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

有三个参数,第二个有5值。

这符合语法,因为内部逗号不能是逗号分隔初始化子句,因为(t=3不是初始化子句。

© www.soinside.com 2019 - 2024. All rights reserved.