[英]Why can I use initializer lists on the right-hand side of operator += but not operator+?
This is a follow-up to an earlier question about why I can't use a brace-enclosed initializer as an argument to operator+
, which was resolved by looking at this earlier question on the subject . 这是一个早期问题的后续问题,为什么我不能使用大括号括起初始化器作为
operator+
的参数 ,这是通过查看前面关于该主题的问题来解决的 。
Consider the following C++ code, which you can try live at ideone.com : 考虑以下C ++代码,您可以在ideone.com上试用 :
#include <iostream>
#include <initializer_list>
using namespace std;
struct AddInitializerList {
void operator+= (initializer_list<int> values) {
// Do nothing
}
void operator+ (initializer_list<int> values) {
// Do nothing
}
};
int main() {
AddInitializerList adder;
adder += {1, 2, 3}; // Totally legit
adder + {1, 2, 3}; // Not okay!
return 0;
}
The line in main
that uses operator+
with a brace-enclosed initializer list does not compile (and, after asking that earlier question, I now know why this is). main
中使用operator+
和大括号括起初始化列表的行不能编译(并且在询问之前的问题后,我现在知道为什么会这样)。 However, I'm confused why the code that uses opeartor+=
in main
does indeed compile just fine. 但是,我很困惑为什么在
main
中使用opeartor+=
的代码确实编译得很好。
I'm confused as to precisely why I can overload +=
and have it work just fine, while overloading +
doesn't seem to work here. 我很困惑,为什么我可以重载
+=
并让它工作得很好,而重载+
似乎在这里工作。 Is there a particular provision in the standard that permits brace-enclosed initializers in the context of the +=
operator but not the +
operator? 标准中是否有特定的规定允许在
+=
运算符但不包含+
运算符的上下文中使用括号括起的初始值设定项? Or is this just a weird compiler quirk? 或者这只是一个奇怪的编译器怪癖?
It is explained in the answer to this question (which is linked from the question you linked to). 这个问题的答案(与您链接的问题相关联) 对此进行了解释。
The language grammar only allows a braced list in certain grammatical contexts, not in place of an arbitrary expression. 语言语法只允许某些语法上下文中的支撑列表,而不是任意表达式。 That list includes the right-hand side of assignment operators, but NOT the right-hand side of operators in general.
该列表包括赋值运算符的右侧,但不包括运算符的右侧。
+=
is an assignment operator, +
is not. +=
是赋值运算符, +
不是。
The grammar for assignment expressions is: 赋值表达式的语法是:
\n assignment-expression:赋值表达式:\n conditional-expression
条件表达式\n logical-or-expression assignment-operator initializer-clause
logical-or-expression assignment-operator initializer-clause\n throw-expression
扔表达\n assignment-operator: one of
赋值运算符:一个\n \n
= *= *= /= %= += -= >>= <<= &= ^= |=
C++14 §5.17/9: C ++14§5.17/ 9:
” A braced-init-list may appear on the right-hand side of
“ braced-init-list可能出现在右侧
- an assignment to a scalar, in which case the initializer list shall have at most a single element.
标量的赋值,在这种情况下,初始化列表最多只能包含一个元素。 The meaning of
x={v}
, whereT
is the scalar type of the expressionx
, is that ofx=T{v}
.x={v}
的含义,其中T
是表达式x
的标量类型,是x=T{v}
的含义。 The meaning ofx={}
isx=T{}
.x={}
的含义是x=T{}
。- an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3).
对类类型对象的赋值,在这种情况下,初始化列表作为参数传递给由重载决策(13.5.3,13.3)选择的赋值运算符函数。
This applies to a +=
b via its $5.7/7 equivalence to a =
a +
b (except that a is evaluated only once for +=
). 这适用于一个
+=
通过其$ 5.7 / 7等价B到A =
一个 +
B(不同之处在于一个用于只计算一次+=
)。 Put another way, due to a comment by MM, because of the equivalence for the built-in operators +=
is regarded as an assignment operator, and not a special update operator. 换句话说,由于MM的评论,由于内置运算符的等价性,
+=
被视为赋值运算符,而不是特殊的更新运算符。 Hence the quoted text above about “assignment” applies to +=
. 因此,上面关于“赋值”的引用文本适用于
+=
。
+=
operator is a compound assignment . +=
运算符是复合赋值 。 The standard explicitly permits initializer lists on the right-hand side of assignments: 该标准明确允许在赋值右侧的初始化列表:
§8.5.4/1 [...] Note: List-initialization can be used
§8.5.4/ 1 [...]注意:可以使用列表初始化
...
...
— on the right-hand side of an assignment (5.17)
- 在作业的右侧(5.17)
§5.17 talks about all assignments, including compound ones: §5.17谈论所有任务,包括复合任务:
assignment-expression:
赋值表达式:
- conditional-expression- 条件表达式
- logical-or-expression assignment-operator initializer-clause- logical-or-expression assignment-operator initializer-clause
- throw-expression- throw-expression
assignment-operator: one of
赋值运算符:一个
=
*=
/=
%=
+=
-=
>>=
<<=
&=
ˆ=
|=
=
*=
/=
%=
+=
-=
>>=
<<=
&=
ˆ=
|=
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.