为什么逗号运算符在运算符 [] 中被调用,而不是在运算符 () 中?
Why is comma operator called inside operator [] but not inside operator ()?
从前一个问题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 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-子句.
从前一个问题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, 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 anyf
declaration, would not try to change the comma status and see iff(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-子句.