用构造函数调用填充向量

时间:2017-06-20 13:30:49

标签: c++ c++11 move-constructor

我有两个课程,一个来自另一个课程。我想分配一个std:vector,它是派生类的填充。棘手的问题是我希望它调用基类中编写的move构造函数。

以下是代码:

class Base{
    public:
    size_t size;
    double* buff;

    Base(size_t _size):size(_size){
        buff = new double[size];
    }

    Base() = delete;
    Base operator=(const Base&) = delete;
    Base(const Base&) = delete;

    Base(Base&& b):size(b.size), buff(b.buff){
        b.buff = nullptr;
    }
    Base operator=(Base&& b){
        size = b.size;
        buff = b.buff;
        b.buff = nullptr;
    }
};

class Derive : public Base{
    public:
    Derive(size_t _size):Base(_size){};
    Derive() = delete;
    Derive operator=(const Derive&) = delete;
    Derive(const Derive&) = delete;

    Derive(Derive&& b):Base(move(b)){}
    Derive operator=(Derive&& b){
        Base::operator=(move(b));
    }
};

/********/

vector<Derive> v(10, move(Derive(5)));

g ++告诉我

error: use of deleted function ‘Derive::Derive(const Derive&)’
 { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }

我不明白我应该做什么。

3 个答案:

答案 0 :(得分:6)

此处的问题是std::vector(count, object) 复制 objectcount次,进入向量。您无法移动它,因为您只能将对象移动到单个对象中。

如果您的课程不可复制,那么您将无法使用它。但是你可以使用

std::vector<Type> foo;
foo.reserve(count);
for (int i = 0; i < count; ++i)
    foo.emplace_back(Types_parmeters);

答案 1 :(得分:5)

您正尝试从一个单一来源构建一个包含10个元素的向量。这是不可能的,因为一旦源元素被移动一次,它就处于未终止状态。

由于这个原因,这个构造函数在草案n4296中为C ++ 14指定使用复制构造函数(强调我的):

  

23.3.6.2向量构造函数,复制和赋值[vector.cons]   
...
vector(size_type n, const T& value, const Allocator& = Allocator());
  效果:使用指定的分配器构造具有n个值副本的向量   要求: T应为CopyInsertable 到* this。   ...

答案 2 :(得分:1)

另一种解决方案是编写可以处理此用例的fill_n版本。典型的fill_n会复制与矢量构造函数相同的内容,但我们可以编写更现代的样式。

template <class T, class OutputIt, class Size, class .. Args>
OutputIt emplace_fill_n(OutputIt first, Size count, const Args& ... args)
{
    for (Size i = 0; i != count; ++i) {
        *first = T(args...);
        ++first;
    }
}

用法:

vector<Derive> v();
v.reserve(10);
emplace_fill_n<Derive>(back_inserter(v), 10);