从数组初始化QVector

4

我从一个函数中接收到一个指向数组的指针,并希望从中初始化一个 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<double>而不是指针和大小,例如void foo(const std::vector<double>& receivedArray) { ... },那么它会更容易和更可靠。在这种情况下,你只需要使用QVector::fromStdVector即可。 - Elijan9
同意,但这不是我的决定。这正是 QVector 的用途。由于数据来自另一个 API,我必须接收 float* 和 size_t,并希望在程序中使用更高级的类型。 - FreddyKay
3个回答

4

第一个方法做了不必要的工作,用默认构造的double类型初始化向量,然后再填充。不幸的是,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 *,这是一个右值,你不能把它放在赋值语句的左边。

1
我在使用reserve和back_inserter时遇到了奇怪的问题。我必须对范围在GB级别的相当大的数组执行上述函数很多次。我注意到,QVector::reserve之后跟着QVector::resize,然后通过迭代器进行简单拷贝的方式表现得更快(约快50%),而不是使用back_inserter的版本。你还记得类似的情况吗? - FreddyKay
1
@FreddyKay 是的,在这种情况下使用您的版本可能更快,原因有两个:1)使用“0”初始化std::vector<double>很快,因为您只需要执行std::memset(data(),0,size() * sizeof(double))(在大多数架构上),2)复制平凡类型也非常快,可以使用std::memcpy(data(),src,size() * sizeof(double))。编译器知道如何针对像double这样的平凡类型优化std::vectorstd::copy,而使用std::back_inserter则非常难以优化。 - Holt
@FreddyKay 还要注意,QVector<double>() 可能预先分配了一些容量,所以如果你之后进行了保留操作,你需要先释放再重新分配。 - Holt
由于涉及到COW(写时复制)机制,QVector<double>()实际上并不预分配任何内存。因此,是的,你需要测量你所做的事情;back_inserter无疑是更通用的解决方案。 - peppe

1

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

0
另一个解决方案:
void foo(double* receivedArray, size_t size)
{
   QVector<double> vec(receivedArray,receivedArray+size);
}

参见: http://cpp.sh/7jfi6


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接