Fill a vector with a constructor call

I have two classes, one of which comes from the other. I would like to highlight std:vectorwhich populates the derived class. The hard question is that I want it to call the move constructor, written in the base class.

Here is the code:

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 ++ tells me

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

and I don’t understand what I have to do.

+4
source share
3 answers

The problem is what std::vector(count, object) copies object , counttimes, to the vector. You cannot move from it, since you can only move an object into one object.

If your class is not copied, you cannot use it. However you can use

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

10 . , , - , .

n4296 ++ 14 ( ):

23.3.6.2 , [vector.cons]
...
vector(size_type n, const T& value, const Allocator& = Allocator());
: n , .
: T CopyInsertable * ....

+4

An alternative solution is to write your own version fill_nthat can handle this use case. A typical one fill_ncopies the same as a vector constructor, but we can write a more modern style.

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;
    }
}

Using:

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

Source: https://habr.com/ru/post/1679723/


All Articles