为啥逗号运算符在运算符[]内部称为逗号运算符而不在运算符()内部调用?
Posted
技术标签:
【中文标题】为啥逗号运算符在运算符[]内部称为逗号运算符而不在运算符()内部调用?【英文标题】:Why is comma operator called inside operator [] but not inside operator ()?为什么逗号运算符在运算符[]内部称为逗号运算符而不在运算符()内部调用? 【发布时间】:2017-12-19 13:38:57 【问题描述】:从前一个问题When all does comma operator not act as a comma operator? 中,我了解到函数调用中的逗号只能充当表达式分隔符。但从下面的代码来看,operator()
的行为类似于函数调用,而operator[]
则不然。
所以我有两个问题:
-
为什么在
operator[]
调用中调用逗号运算符而不在operator()
调用中调用?
是否存在阻止编译器的特定原因,首先检查 f(a,b)
是否与任何 f 声明的 arity 或类型都不匹配,不会尝试更改逗号状态并查看 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;
【问题讨论】:
看看“表达式”可以在语法中的什么地方使用。不是表达式中的参数包。数组索引是一个表达式。逗号运算符只能用于表达式。在某些情况下,用圆括号括起来可以将它们变成表达式。如需完整答案,请添加语言律师标签和/或阅读标准。 好吧,operator()
被称为"function call operator",因为它被使用(并且解析)。
那不会使代码更具可读性,你不觉得吗?
如果operator,
的存在可以决定z(x,y)
是否有一个或两个参数,那将是令人难以置信的混乱。
@molbdnilo:这太轻描淡写了。在存在重载的情况下,您甚至不知道要考虑 哪个 f
。当f
接受两个参数时,如何看待f(x,y,z)
- 你是否同时尝试f(x,(y,z))
和f((x,y),z)
?
【参考方案1】:
为什么在
operator[]
调用中调用逗号运算符而不在operator()
调用中调用?
如果你看grammatically,函数调用的形式是postfix-expression (
expression-listopt)
. 表达式列表(这是一个initializer-list,不要与std::initializer_list
混淆)是一个comma separated list of initializer-clauses(假设至少有两个子句)。逗号被 expression-list 的解析所消耗,其中它具有特殊含义,而不是表达式的一部分。
索引的形式是 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
。
这在语法上有效,因为内部逗号不能是分隔 initializer-clause 的逗号,因为 (t=3
不是 initializer-clause。
【讨论】:
除了这个想法的一般疯狂之外,你不知道你在看哪个f
s,直到你知道参数(因为 ADL),如果你不知道是什么参数直到您知道存在哪些f
s...以上是关于为啥逗号运算符在运算符[]内部称为逗号运算符而不在运算符()内部调用?的主要内容,如果未能解决你的问题,请参考以下文章