【问题标题】:Initialize QVector from array从数组初始化 QVector
【发布时间】:2016-08-12 13:06:40
【问题描述】:

我从一个函数接收一个数组作为指针,并希望从中初始化一个 QVector。

现在我这样做:

void foo(double* receivedArray, size_t size)
{
    QVector<double> vec(size);

    std::copy(receivedArray, receivedArray + size, std::begin(vec));
}

是否也可以这样做:

void foo(double* receivedArray, size_t size)
{
    QVector<double> vec(size);

    vec.data() = receivedArray;
}

这会破坏某种我不知道的 Qt 机制吗?

【问题讨论】:

  • 不是一个答案,但如果foo 会收到一个双精度的 std::vector 而不是指针和大小,例如void foo(const std::vector&lt;double&gt;&amp; receivedArray) { ... }。在这种情况下,您只需要QVector::fromStdVector
  • 同意,但这不取决于我。这实际上是 QVector 的重点。我必须接受带有 size_t 的 float*,因为它来自另一个 API,并且希望在我的程序中使用更高级的类型。

标签: c++ qt copy


【解决方案1】:

第一个做不必要的工作,在填充之前使用默认构造的双精度值初始化向量。不幸的是,QVector 缺少范围插入,因此您必须求助于算法:

void foo(double* receivedArray, size_t size)
{
    QVector<double> vec;
    vec.reserve(size); // warning: size_t->int cast

    std::copy(receivedArray, receivedArray + size, std::back_inserter(vec));
}

第二个版本甚至无法编译,因为data() 返回一个T *,这是一个不能放在赋值左侧的右值。

【讨论】:

  • 我遇到了一个关于reserve 和back_inserter 的奇怪问题。我必须在 GB 范围内使用相当大的数组多次执行上述功能。我观察到 QVector::reserve 后跟 QVector::resize,然后通过简单的复制,迭代器的行为比 back_inserter 版本快(大约 50%)。你还记得类似的行为吗?
  • @FreddyKay 是的,在这种特定情况下使用您的版本可能会更快,原因有两个:1)使用0 初始化std::vector&lt;double&gt; 很快,因为您只需要执行std::memset(data(), 0, size() * sizeof(double))(在大多数架构上)和 2)使用std::memcpy(data(), src, size() * sizeof(double)) 复制普通类型也非常快。编译器知道如何优化 std::vectorstd::copy 用于诸如 double 这样的普通类型,另一方面,使用 std::back_inserter 确实很难优化。
  • @FreddyKay 另请注意,QVector&lt;double&gt;() 可能预先分配了一些容量,因此如果您之后保留,则需要解除分配然后重新分配。
  • 由于涉及到 COW,QVector&lt;double&gt;() 实际上并没有预先分配任何东西。然后,是的,你需要衡量你在做什么; back_inserter 肯定是更通用的解决方案。
【解决方案2】:

QVector::data 不返回对底层指针的引用,因此您不能分配给vec.data()(它不是左值,它甚至不会编译):

template <typename T>
struct Vector {
    T* data_;

    T* nref_data () { return data_; }
    T* &ref_data () { return data_; }
};

Vector<int> vec;
vec.ref_data() = new int[100]; // Ok, Vector<int>::ref_data returns a reference
vec.nref_data() = new int[100]; // Nok, Vector<int>::nref_data does not return a reference

【讨论】:

    猜你喜欢
    • 2014-01-22
    • 2023-03-20
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2021-01-31
    • 2011-06-05
    相关资源
    最近更新 更多