【C++】独自クラスをpush_backした際のコピーコンストラクタに関するエラー

C++

以下の C++ コードはコンパイル時にエラーが出ます。

sample.cpp

#include <vector>

class Class1
{
public:
  Class1() {}
  Class1(Class1 &src) {}
};

int main()
{
  std::vector<Class1> v;
  Class1 c;
  v.push_back(c);
}

以下がエラー出力です。

In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/vector:61,
                 from sample.cpp:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Class1; _Args = {const Class1&}; _Tp = Class1]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Class1; _Args = {const Class1&}; _Tp = Class1; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<Class1>]’
/usr/include/c++/7/bits/stl_vector.h:943:30:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Class1; _Alloc = std::allocator<Class1>; std::vector<_Tp, _Alloc>::value_type = Class1]’
sample.cpp:14:16:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: binding reference of type ‘Class1&’ to ‘const Class1’ discards qualifiers
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sample.cpp:7:3: note:   initializing argument 1 of ‘Class1::Class1(Class1&)’
   Class1(Class1 &src) {}
   ^~~~~~
In file included from /usr/include/c++/7/vector:62:0,
                 from sample.cpp:1:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Class1; _Args = {Class1}]’:
/usr/include/c++/7/bits/stl_uninitialized.h:83:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Class1*>; _ForwardIterator = Class1*; bool _TrivialValueTypes = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:134:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Class1*>; _ForwardIterator = Class1*]’
/usr/include/c++/7/bits/stl_uninitialized.h:289:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<Class1*>; _ForwardIterator = Class1*; _Tp = Class1]’
/usr/include/c++/7/bits/stl_uninitialized.h:311:2:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = Class1*; _ForwardIterator = Class1*; _Allocator = std::allocator<Class1>]’
/usr/include/c++/7/bits/vector.tcc:426:6:   required from ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const Class1&}; _Tp = Class1; _Alloc = std::allocator<Class1>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Class1*, std::vector<Class1> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Class1*]’
/usr/include/c++/7/bits/stl_vector.h:948:21:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Class1; _Alloc = std::allocator<Class1>; std::vector<_Tp, _Alloc>::value_type = Class1]’
sample.cpp:14:16:   required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: cannot bind non-const lvalue reference of type ‘Class1&’ to an rvalue of type ‘Class1’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sample.cpp:7:3: note:   initializing argument 1 of ‘Class1::Class1(Class1&)’
   Class1(Class1 &src) {}
   ^~~~~~

push_backによって呼ばれるコピーコンストラクタに関して型が合わないという内容です。

これを修正するには、コピーコンストラクタの引数に const をつけます。

Class1(const Class1 &src) {}

このような問題を避けるため、コピーコンストラクタの引数は常に const にしておきましょう。

コメント

タイトルとURLをコピーしました