У меня есть классы A
и B
.
B
происходит от A
.
У меня также есть вектор std::vector<std::unique_ptr<A>> samples
Этот фрагмент кода работает:
std::vector<std::unique_ptr<A>> samples;
samples.push_back(std::make_unique<B>(param_1, param_2));
А вот этого нет:
std::vector<std::unique_ptr<A>> samples = {std::make_unique<B>(param_1, param_2)};
и выдает такую ошибку:
/usr/include/c++/9/bits/stl_uninitialized.h: In instantiation of ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const std::unique_ptr<A>*; _ForwardIterator = std::unique_ptr<A>*]’:
/usr/include/c++/9/bits/stl_uninitialized.h:307:37: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const std::unique_ptr<A>*; _ForwardIterator = std::unique_ptr<A>*; _Tp = std::unique_ptr<A>]’
/usr/include/c++/9/bits/stl_vector.h:1582:33: required from ‘void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::unique_ptr<A>*; _Tp = std::unique_ptr<A>; _Alloc = std::allocator<std::unique_ptr<A> >]’
/usr/include/c++/9/bits/stl_vector.h:626:2: required from ‘std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = std::unique_ptr<A>; _Alloc = std::allocator<std::unique_ptr<A> >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::unique_ptr<A> >]’
my_file.cpp:88:113: required from here
/usr/include/c++/9/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
127 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
make: *** [makefile:15: cpp] Error 1
Вопросы
1. Связана ли эта ошибка с отсутствием правильного конструктора в vector
(interator
?) или в A/B
классе?
2. Когда я делаю push_back
, должен ли я всегда делать std:move
с unique_pointer
или нет? Спрашиваю, потому что сомневаюсь, может быть, без std::move
неявно создаются какие-то копии. С другой стороны, может быть, компилятор произведет некоторые оптимизации и сможет распознать такую «короткую» конструкцию?