我必须对AB进行分类。B源自A
我也有 vector 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:moveunique_pointer一起使用?我问是因为我怀疑是否没有std::move会隐式创建一些副本。另一方面,也许编译器进行了一些优化,并且可以识别这种“短”结构?

最佳答案



两者都不是因为std::unique_ptr的副本构造函数被隐式删除(由于用户声明了move构造函数);您无法复制std::unique_ptr,而是将其移动。



是的,当在带有左值参数的push_back元素的 vector 上调用std::unique_ptr时,您需要使用std::move来调用std::unique_ptr的move构造函数(而不是其隐式删除的副本构造函数)。

#include <memory>
#include <vector>

int main() {
    std::vector<std::unique_ptr<int>> v;
    auto value = std::make_unique<int>(1);

    // v.push_back(value);                  // error (attempts to copy)
    v.push_back(std::move(value));          // lvalue "std::to_xvalue" -> move ctor
    v.push_back(std::make_unique<int>(2));  // already an rvalue -> move ctor
    return 0;
}

09-10 01:27
查看更多