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.
Consider the following C++ code, which you can 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;
}
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). However, I'm confused why the code that uses opeartor+=
in main
does indeed compile just fine.
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?
+=
operator is a compound assignment. The standard explicitly permits initializer lists on the right-hand side of assignments:§5.17 talks about all assignments, including compound ones:
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:
C++14 §5.17/9:
This applies to a
+=
b via its $5.7/7 equivalence to a=
a+
b (except that a is evaluated only once for+=
). Put another way, due to a comment by M.M., because of the equivalence for the built-in operators+=
is regarded as an assignment operator, and not a special update operator. Hence the quoted text above about “assignment” applies to+=
.