为什么我可以在 operator += 的右侧使用初始化列表而不是 operator+?
Why can I use initializer lists on the right-hand side of operator += but not operator+?
这是 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 的后续。
考虑以下 C++ 代码,您可以 try live at 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;
}
main
中将 operator+
与大括号括起来的初始化列表一起使用的行无法编译(而且,在问了之前的问题之后,我现在知道这是为什么了)。但是,我很困惑为什么在 main
中使用 operator+=
的代码确实编译得很好。
我很困惑为什么我可以重载 +=
并让它工作得很好,而重载 +
在这里似乎不起作用。标准中是否有特定条款允许在 +=
运算符而不是 +
运算符的上下文中使用大括号括起来的初始值设定项?或者这只是一个奇怪的编译器怪癖?
+=
运算符是一个 复合赋值 。该标准明确允许赋值右侧的初始化列表:
§8.5.4/1 [...] Note: List-initialization can be used
...
— on the right-hand side of an assignment (5.17)
§5.17 讨论所有作业,包括复合作业:
assignment-expression:
- conditional-expression
- logical-or-expression assignment-operator initializer-clause
- throw-expression
assignment-operator: one of
=
*=
/=
%=
+=
-=
>>=
<<=
&=
ˆ=
|=
this question 的答案中有解释(链接自您链接到的问题)。
语言语法只允许在某些语法上下文中使用大括号列表,而不是任意表达式的位置。该列表包括赋值运算符的右侧,但不包括一般运算符的右侧。
+=
是赋值运算符,+
不是。
赋值表达式的语法是:
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
assignment-operator: one of
= *= *= /= %= += -= >>= <<= &= ^= |=
C++14 §5.17/9:
” A braced-init-list may appear on the right-hand side of
- an assignment to a scalar, in which case the initializer list shall have at most a single element. The meaning of
x={v}
, where T
is the scalar type of the expression x
, is that of x=T{v}
. The meaning of x={}
is 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).
这适用于 a+=
b 通过其 $5.7/7 等价于 a=
a+
b(除了 a 是仅对 +=
评估一次)。换句话说,由于 M.M 的评论,由于内置运算符的等价性 +=
被视为赋值运算符,而不是特殊的更新运算符。
因此,上面引用的关于“赋值”的文字适用于 +=
.
这是 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 的后续。
考虑以下 C++ 代码,您可以 try live at 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;
}
main
中将 operator+
与大括号括起来的初始化列表一起使用的行无法编译(而且,在问了之前的问题之后,我现在知道这是为什么了)。但是,我很困惑为什么在 main
中使用 operator+=
的代码确实编译得很好。
我很困惑为什么我可以重载 +=
并让它工作得很好,而重载 +
在这里似乎不起作用。标准中是否有特定条款允许在 +=
运算符而不是 +
运算符的上下文中使用大括号括起来的初始值设定项?或者这只是一个奇怪的编译器怪癖?
+=
运算符是一个 复合赋值 。该标准明确允许赋值右侧的初始化列表:
§8.5.4/1 [...] Note: List-initialization can be used
...
— on the right-hand side of an assignment (5.17)
§5.17 讨论所有作业,包括复合作业:
assignment-expression:
- conditional-expression
- logical-or-expression assignment-operator initializer-clause
- throw-expressionassignment-operator: one of
=
*=
/=
%=
+=
-=
>>=
<<=
&=
ˆ=
|=
this question 的答案中有解释(链接自您链接到的问题)。
语言语法只允许在某些语法上下文中使用大括号列表,而不是任意表达式的位置。该列表包括赋值运算符的右侧,但不包括一般运算符的右侧。
+=
是赋值运算符,+
不是。
赋值表达式的语法是:
assignment-expression: conditional-expression logical-or-expression assignment-operator initializer-clause throw-expression assignment-operator: one of= *= *= /= %= += -= >>= <<= &= ^= |=
C++14 §5.17/9:
” A braced-init-list may appear on the right-hand side of
- 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}
. The meaning ofx={}
isx=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).
这适用于 a+=
b 通过其 $5.7/7 等价于 a=
a+
b(除了 a 是仅对 +=
评估一次)。换句话说,由于 M.M 的评论,由于内置运算符的等价性 +=
被视为赋值运算符,而不是特殊的更新运算符。
因此,上面引用的关于“赋值”的文字适用于 +=
.