保证大型std :: vector的移动

时间:2017-03-08 07:37:07

标签: c++ qt c++11 vector

我有一个大型数据集(几千兆字节)存储在一个不符合QVector(最大~2gb)的文件中,该文件是写时复制的,不会受此影响。我将向量加载到内存中,如下所示:

std::vector<int> load()
{
    std::vector<int> vec;
    QFile file("filename");
    file.open(QIODevice::ReadOnly);
    QDataStream stream(&file);
    stream >> vec; //using my implementation of QDataStream &operator>>(QDataStream &stream, std::vector<int> &v)
    return vec;
}

并将其传递给:

class Data
{
public:
    Data(const std::vector<int> &data) :
        d(data)
    {
    }

private:
    std::vector<int> d;
};
像那样:

Data data(load());

现在在load()中,矢量被创建并填充文件中的数据。然后它按值返回,但我相信它应该由编译器优化,不要实际复制vec,而是将其移动到目的地。

目的地是Data的私有成员,但是我怀疑构造函数中的初始化列表可能实际上是复制了向量而不是移动它,因为它不知道(或者是吗?)它已经收到了一个const引用临时的。

有没有办法保证矢量只会在构造后移动而不会在这种情况下被复制?我怀疑使用std::movestd::forward或更改Data::Data()的签名来获取r值参考?

1 个答案:

答案 0 :(得分:6)

您可以添加一个带有右值引用的构造函数,然后用它复制构造数据成员:

Data(std::vector<int>&& data) :
    d(std::move(data)) {}

Data(const std::vector<int>& data) // as before

有一个较短的版本,你将构造函数重载替换为1,并按值获取参数。请注意,这依赖于rvalue参数的复制省略,以避免任何额外的移动副本。它可能比两个重载解决方案做更多的工作,但与复制大型向量 * 的内容相比,工作量最小。它也可能需要一些额外的头部刮痕,虽然它已经变得有些惯用:

Data(std::vector<int> data) :
    d(std::move(data)) {}

*见this related post,特别是Howard Hinnant的回答。