Why const member caused error?
#include <vector>
class B {
};
class A {
const std::vector<B> m_v;
public:
A(const std::vector<B>& v) : m_v(v) {}
void doSomething() {}
};
void foo(void* bar) {
A* a = (A*)bar;
a->doSomething();
}
int main() {
std::vector<B> v;
std::vector<A > l;
for (auto i = 0; i < 10; i++) {
A a(v);
l.push_back(std::move(a));
foo((void*)&l[i]);
}
return 0;
}
$ g++ -Wall initList.cpp -o initList -lrt -O3 -std=c++0x In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0, from initList.cpp:1: /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function u2018void std::vector::_M_insert_aux(std::vector::iterator, _Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator, std::vector::iterator = __gnu_cxx::__normal_iterator >, typename std::_Vector_base::_Tp_alloc_type::pointer = A*]`: /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from u2018void std::vector::emplace_back(_Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:840:9: instantiated from u2018void std::vector::push_back(std::vector::value_type&&) [with _Tp = A, _Alloc = std::allocator, std::vector::value_type = A]` initList.cpp:23:27: instantiated from here /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: use of deleted function '& A::operator=(const A&)` initList.cpp:6:7: error: '& A::operator=(const A&)` is implicitly deleted because the default definition would be ill-formed: initList.cpp:6:7: error: passing u2018const std::vector` as u2018this` argument of u2018std::vector& std::vector::operator=(const std::vector&) [with _Tp = B, _Alloc = std::allocator]` discards qualifiers [-fpermissive] In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:61:0, from initList.cpp:1: /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function u2018static _BI2 std::__copy_move_backward::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]`: /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from u2018_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from u2018_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = A*, _BI2 = A*]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from u2018_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = A*, _BI2 = A*]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from u2018void std::vector::_M_insert_aux(std::vector::iterator, _Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator, std::vector::iterator = __gnu_cxx::__normal_iterator >, typename std::_Vector_base::_Tp_alloc_type::pointer = A*]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from u2018void std::vector::emplace_back(_Args&& ...) [with _Args = {A}, _Tp = A, _Alloc = std::allocator]` /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:840:9: instantiated from u2018void std::vector::push_back(std::vector::value_type&&) [with _Tp = A, _Alloc = std::allocator, std::vector::value_type = A]` initList.cpp:23:27: instantiated from here /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function '& A::operator=(const A&)`
If I don't specify const for m_v. It compiles fine.
The error suggests something with assign operator, which I don't see how it is invoked.
Any idea?
Thanks in advance.
It's a bug in older versions of GCC/libstdc++, your code compiles fine with GCC 4.8.1. Live example . The bug is triggered by
l.push_back(std::move(a));
as older versions of GCC tried to create a default-constructed element in the vector and assigned the parameter std::move(a)
to it in a second step instead of using the in-place copy/move-ctor.
上一篇: 如何从函数返回对?
下一篇: 为什么const成员造成错误?