C ++可以使用移动语义将数据从一个向量移动到另一个向量

问题描述 投票:1回答:4

下面的代码将数据从一个向量复制到另一个向量。如果矢量很大,那么我猜这很贵。是否可以在此处使用移动语义将数据从一个向量复制到另一个向量?

std::vector<double> newData(Shape.Size(), 0);
std::vector<double> oldData = a->getData();
std::copy(oldData.begin(), oldData.end(), newData.begin());
c++ c++11 vector move-semantics
4个回答
5
投票

您可以使用算法std::move而不是std::copy

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

它仍将按元素传输元素,但会移动它们。不要忘记预先分配具有正确大小的向量,以避免过多地移动元素。


4
投票

是的,你可以用std::move_iterator做到这一点。

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

正如@tkausl所说,这对内置类型的vector没有多大意义;最后在这种情况下执行复制。你可能想直接移动vector,例如

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

要么

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

0
投票

在提供的示例中,移动或复制没有区别,因为向量中的值在移动期间不执行任何空间动作(它是双倍)。

这是一个合理的例子:

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

注意

 dst = std::move(data);

将更快,因为数据缓冲区将被简单地重新分配给另一个向量。

https://wandbox.org/permlink/pJnmrWYe40hLRYNE

其他答案使用make_move_iterator。如果与其他算法一起使用,这是实用的。随着复制/移动不是很实用。


-1
投票

我假设你对移动语义感到困惑。如果必须保留旧数据属于旧位置,则无法使用移动语义。移动语义意味着将数据从旧移动到新移动。

格林威治标准时间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));是一个移动语义,检查此后剩下的向量a。

© www.soinside.com 2019 - 2024. All rights reserved.