c++ - std::vector 不使用具有 noexcept move 构造的对象调用 move 构造函数

标签 c++ c++14 copy-constructor move-semantics move-constructor

最近我一直在为 move 和复制构造函数苦苦挣扎,似乎无法自己找到 awnser。 结构相当简单。一个 OWUP 类,它持有一个对象的 std::unique_ptr(在这个例子中是一个 int),一个类 One 是一个简单的包装 std::OWUP 的 vector 和一个类 Two,它是一个简单的包装 std::vector 的 OWUP .

#include <memory>
#include <vector>

class OWUP {
public:
    OWUP()
    : data(nullptr)
    { }

    OWUP(const OWUP &) = delete;
    OWUP &operator=(const OWUP &) = delete; 
    OWUP(OWUP &&) noexcept = default;
    OWUP &operator=(OWUP &&) noexcept = default; 

    std::unique_ptr<int> data; 
};

class One {
public:
    One(std::size_t numof_datas)
    : datas(numof_datas)
    { }

    One(const One &) = delete;
    One &operator=(const One &) = delete; 
    One(One &&) noexcept = default;
    One &operator=(One &&) noexcept = default; 

    std::vector<OWUP> datas;
};

class Two {
public:
    Two(std::size_t numof_ones, std::size_t num_of_datas)
    : ones(numof_ones, One(num_of_datas))
    { }

    Two(const Two &) = delete;
    Two &operator=(const Two &) = delete; 
    Two(Two &&) noexcept = default;
    Two &operator=(Two &&) noexcept = default;

    std::vector<One> ones;
}; 

代码用g++ -std=c++14 example.cpp得到如下错误码

In file included from /usr/include/c++/7.3.1/memory:64:0,
                 from example.cpp:1:
/usr/include/c++/7.3.1/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = One; _Args = {const One&}]':
/usr/include/c++/7.3.1/bits/stl_uninitialized.h:210:18:   required from 'static _ForwardIterator std::__uninitialized_fill_n<_TrivialValueType>::__uninit_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = One*; _Size = long unsigned int; _Tp = One; bool _TrivialValueType = false]'
/usr/include/c++/7.3.1/bits/stl_uninitialized.h:255:17:   required from '_ForwardIterator std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = One*; _Size = long unsigned int; _Tp = One]'
/usr/include/c++/7.3.1/bits/stl_uninitialized.h:366:39:   required from '_ForwardIterator std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>&) [with _ForwardIterator = One*; _Size = long unsigned int; _Tp = One; _Tp2 = One]'
/usr/include/c++/7.3.1/bits/stl_vector.h:1337:33:   required from 'void std::vector<_Tp, _Alloc>::_M_fill_initialize(std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = One; _Alloc = std::allocator<One>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = One]'
/usr/include/c++/7.3.1/bits/stl_vector.h:298:27:   required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = One; _Alloc = std::allocator<One>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = One; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<One>]'
example.cpp:40:39:   required from here
/usr/include/c++/7.3.1/bits/stl_construct.h:75:7: error: use of deleted function 'One::One(const One&)'
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
example.cpp:29:3: note: declared here
   One(const One &) = delete;
   ^~~

我已尽力强制它使用 move 构造函数。我还尝试使用 std::move 创建自己的 move 构造函数,但这导致了相同的编译错误。我知道 std::vector 测试 move_if_noexcept(),但无法找出原因。我做错了什么?

最佳答案

因为问题出在这里:

Two(std::size_t numof_ones, std::size_t num_of_datas)
: ones(numof_ones, One(num_of_datas))
{ }

你不能从你在这里创建的 One move ,你真的需要从它复制 numof_ones 次。

关于c++ - std::vector 不使用具有 noexcept move 构造的对象调用 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49904301/

相关文章:

c++ - 警告 : specialization of template in different namespace

c++ - 如何使用 C++11 创建高效的闭包?

c++ - 编译时抽象类处理中的 clang vs gcc

C++ 引用可以赋值吗?

c++ - 在没有分配和内存复制的情况下从数组中创建 vector

c++ - 从基本指针的源容器构造一个派生指针的容器

c++ - 为什么 gcc 警告使用 std::tuple 和虚拟继承调用非平凡的移动赋值运算符?

c++ - 一个类的多个接口(interface)

c++ - 即使从未调用过,是否也需要拷贝 CTOR?

c++ - 返回值优化不适用于 const unique_ptr 成员?