black sheep
black sheep

Reputation: 399

C++ possible to use move sematics to move data from one vector to another

The code below copies data from one vector into another. If the vectors are large then I guess this is expensive. Is it possible to use move semantics here to copy data from one vector into another?

std::vector<double> newData(Shape.Size(), 0);
std::vector<double> oldData = a->getData();
std::copy(oldData.begin(), oldData.end(), newData.begin());

Upvotes: 2

Views: 2358

Answers (4)

Dahn Park
Dahn Park

Reputation: 1

I assuming you are confused about move semantics. If you must keep your old data belong to old place, there are no way to use move semantics. Move semantic means move data out from old to new.

Additional GMT 18:50

#include <iostream>
#include <vector>

#include <cstdlib>
#include <ctime>

#include <cstdint>

int main()
{
    std::srand(std::time(nullptr));

    const int LEN_SHAPE = 1024;
    std::vector<double> a;
    int n = LEN_SHAPE;
    while (n--)
    {
        a.push_back( ((double)std::rand() / RAND_MAX) * std::numeric_limits<double>::max() );
    }

    std::vector<double> newData(a.size(), 0);
    std::vector<double> oldData( std::move( a ));
    std::copy(oldData.begin(), oldData.end(), newData.begin());

}

std::vector oldData( std::move( a )); is a move semantic, check after this what remains in vector a.

Upvotes: -1

Marek R
Marek R

Reputation: 37512

In the provided example move or copy there is no difference, since values in vector do not perform any spatial actions during move (it a double).

Here is reasonable example:

 using FooPtr = std::shared_ptr<Foo>;

 constexpr size_t n = 100;
 std::vector<FooPtr> data;
 data.reserve(n);
 std::generate_n(std::back_inserter(data), n, FooFactory);

 std::vector<FooPtr> dst;
 dst.reserve(n);
 std::move(std::begin(data), std::end(data), std::back_inserter(dst));

Note that

 dst = std::move(data);

Will be faster since data buffer simply will be reassigned to the other vector.

https://wandbox.org/permlink/pJnmrWYe40hLRYNE

Other answer uses make_move_iterator. This is practical if used with other algorithms. With copy/move is not very practical.

Upvotes: 0

songyuanyao
songyuanyao

Reputation: 172864

Yes you can do it with std::move_iterator.

std::copy(std::make_move_iterator(oldData.begin()), 
          std::make_move_iterator(oldData.end()), 
          newData.begin());

As @tkausl said this doesn't make much sense for vector of built-in types; copy is performed in this case at last. You might want to move the vector directly, e.g.

std::vector<double> newData = std::move(oldData); // move construction

or

newData = std::move(oldData); // move assignment

Upvotes: 5

Guillaume Racicot
Guillaume Racicot

Reputation: 41750

You could use the algorithm std::move instead of std::copy:

std::move(oldData.begin(), oldData.end(), newData.begin());

It will still transfer elements by elements, but will move them instead. Don't forget to pre-allocate the vector with the right size to avoid moving elements around too much.

Upvotes: 7

Related Questions