来自前一个问题 When all does comma operator not act as a comma operator? ,我知道函数调用中的逗号只能充当表达式分隔符。但是从下面的代码来看,operator()
的行为类似于函数调用,而 operator[]
则不然。
所以我有两个问题:
- 为什么逗号运算符在
operator[]
调用中调用,而不是在operator()
调用中调用? - 是否有特定原因阻止编译器首先检查
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 anoperator()
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 anyf
declaration, would not try to change the comma status and see iff(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/