c++ - 为什么要调用复制构造函数来构造一个空的 unique_ptr vector ?

标签 c++ vector copy-constructor

#include <vector>
#include <memory>
#include <iostream>

class A {
    std::vector<std::unique_ptr<int>> vec;
public:
    virtual ~A() = 0;
};

A::~A() {}

class B : public A {
public:
    B() {}
};

int main () {
    B b = B();
    return 0;
}

以上是一个最小的可重现示例。编译不通过,报错如下:

me:~ $ g++ main2.cc
In file included from /usr/include/c++/7/vector:62:0,
                 from main2.cc:1:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::unique_ptr<int>; _Args = {const std::unique_ptr<int, std::default_delete<int> >&}]’:
/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 = __gnu_cxx::__normal_iterator<const std::unique_ptr<int>*, std::vector<std::unique_ptr<int> > >; _ForwardIterator = std::unique_ptr<int>*; bool _TrivialValueTypes = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:134:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<int>*, std::vector<std::unique_ptr<int> > >; _ForwardIterator = std::unique_ptr<int>*]’
/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 = __gnu_cxx::__normal_iterator<const std::unique_ptr<int>*, std::vector<std::unique_ptr<int> > >; _ForwardIterator = std::unique_ptr<int>*; _Tp = std::unique_ptr<int>]’
/usr/include/c++/7/bits/stl_vector.h:331:31:   required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<int>; _Alloc = std::allocator<std::unique_ptr<int> >]’
main2.cc:5:7:   required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/memory:80:0,
                 from main2.cc:2:
/usr/include/c++/7/bits/unique_ptr.h:388:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^~~~~~~~~~

这一切看起来像是在某处调用了 unique_ptr 的复制构造函数。

但我完全不知道为什么会调用它。初始化 vector 时,它的大小为 0,对吗?在此假设下,不应构造 unique_ptr

我的编译错误的来源是什么?

最佳答案

B b = B() 是一个复制初始化,在 C++17 之前,要求复制有效(即使它最终被省略)。

即使该拷贝中 vector 的大小为零,这也不是编译时复制机制的内部结构可以静态知道的。因此,使其工作的代码必须在编译期间“已知”,以便在需要时在运行时可用。

你的意思可能只是一个普通的声明:B b;

如果您的类是普通可移动的(因为 unique_ptr 可以移动),原来的方法实际上已经足够了,但是通过给它一个用户声明的析构函数,您就悲观了。除非你真的有充分的理由希望这个类是多态的,否则不要那样做。使用 = default 或完全省略析构函数;它没有做任何有用的事情。

关于c++ - 为什么要调用复制构造函数来构造一个空的 unique_ptr vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59020886/

相关文章:

c++ - 为什么 const_cast 的行为不如预期?

c++ - UML 中的 Const 函数规范

c++ - QSharedMemory 不会在应用程序崩溃时被删除

c++ - 海湾合作委员会 : Specifying static/dynamic libraries to build against

c++ - 使用 std::sort 在自定义类 C++ 中对 vector 进行排序

c++ - myvector 没有命名类型

string - 在 Rust 中将 Vec<String> 转换为 &str 的一部分?

继承中的 C++ 复制构造函数

c++ - 让 shared_ptr 成员破坏 CopyConstructible 契约吗?

c++ - wglCreateContextAttribsARB 在有能力的硬件上返回 NULL