It seems that adding a default constructor prevents from calling emplace_back
and produces the error message: "static assertion failed: type is not assignable" (gcc 5.3 with -std=c++14). Here is a simple code that illustrates the issue:
class A {
public:
int a;
A() = default;
A(int a) {
this->a = a;
}
A(A const & a) = delete;
A& operator =(A const & a) = delete;
A(A && a) = default;
A& operator =(A && a) = default;
};
int main() {
A a(4);
std::vector<A> vec;
vec.emplace_back(std::move(a)); // Error: type is not assignable
return 0;
}
When removing the default constructor, the error goes away! Also, if the default constructor is defined (even if it does nothing), the error also goes away:
class A {
public:
int a;
A() {
}
A(int a) {
this->a = a;
}
A(A const & a) = delete;
A& operator =(A const & a) = delete;
A(A && a) = default;
A& operator =(A && a) = default;
};
int main() {
A b;
A a(4);
std::vector<A> vec;
vec.emplace_back(std::move(a)); // Error gone
return 0;
}
It seems that "A() = default;" is what is causing the problem. Is this normal behaviour on part of the compiler or is it a bug?
It's a libstdc++ bug (edit: reported as bug 69478 ).
Briefly, libstdc++'s std::vector
, as relevant here, uses std::uninitialized_copy
(paired with move iterators) to move elements on reallocation, which is reduced to std::copy
if the type is trivial and the iterators' reference types are assignable (ie, the assignment operator that would conceptually be used is usable).
Then, the std::copy
for pointers to trivial types (or in our case, a move_iterator
wrapping a pointer) is in turn optimized into a call to memmove
coupled with a check for is_copy_assignable
. Of course, that check is wrong in this case, since the uninitialized_copy
, paired with move iterators, only requires the thing to be move constructible.
When you don't have a default constructor or if the default constructor is user-defined, then the class isn't trivial, so you don't hit the code path that triggers this bug.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.