I have some compilation problems pushing back elements of type T to a vector when compiling with g++ -std=c++0x.
This is a minimal example:
#include <
I'm quite sure this is a safety feature. Types with a copy-assignment operator (or a copy constructor) that may mutate the right-hand side are not safe to use in standard containers - an example of this is (the now deprecated) std::auto_ptr
which will break horribly if stored in a container.
The old C++03 library implementation permitted such unsafe code, but apparently they implemented a compile-time check in the C++0x version -- probably in conjunction with move-enabling the containers.
The standard's definition of copy-assignment operator is (section [class.copy]
):
A user-declared copy assignment operator
X::operator=
is a non-static non-template member function of classX
with exactly one parameter of typeX
,X&
,const X&
,volatile X&
orconst volatile X&
.
But the X&
and volatile X&
variants may not be compatible with containers assuming an assignment can be made from an r-value RHS.
NOTE: Passing by value, e.g. X::operator=(X)
is a fundamental part of the copy-and-swap idiom.
The Assignable requirement imposted by the language standard on the standard container elements requires the t = u
expression to be valid even if u
is a const object. The requirement was defined that way since C++98 (see 23.1/4)
You violated that requirement, since your assignment operator does not accept const objects. This immediately mean that your class A
cannot be used as a container element type.
Why it worked in C++03 is rather irrelevant. It worked by accident. It is obvious from the error message that the C++0x implementation of the library uses some C++0x specific features (like std::move
), which is what makes the above requirement to come into play. But anyway, a C++03 implementation (and even C++98 implementation) can also fail to compile for your A
.
Your example with A c = a;
is irrelevant, since it does not use the assignment operator at all (why is it here?).
In order to fix the error you should either accept the parameter by const reference or by value.