2016-08-12 2664 views
2

我收到一个数组作为函数的指针,并希望从中初始化一个QVector。从数组初始化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的机制,我不知道的?

+0

不是一个答案,但是如果'foo'会收到一个std :: double而不是一个指针和大小的向量,例如它会更容易和更傻。 'void foo(const std :: vector &receivedArray){...}'。在这种情况下,你需要的只是'QVector :: fromStdVector'。 – Elijan9

+0

同意,但这不取决于我。这实际上是QVector的重点。我必须接受float * with size_t,因为这是来自另一个API,并且想要在我的程序中使用mor高级类型。 – FreddyKay

回答

2

第一个做不必要的工作,初始化在填充之前带有缺省构造的双精度的矢量。不幸的是,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

我有一个奇怪的问题,保留和back_inserter。我必须用GB范围内的相当大的数组来执行上述功能。我观察到QVector :: reserve后跟QVector :: resize,然后通过迭代器进行简单复制,比back_inserter版本表现得更快(大约50%)。你还记得一个类似的行为吗? – FreddyKay

+1

@FreddyKay是的,使用你的版本可能在这种特定情况下更快,原因有两个:1)用'0'初始化'std :: vector '速度很快,因为你只需要执行一个'std :: memset(data (),0,size()* sizeof(double))'(在大多数架构上)和2)复制trivial类型也是非常快速的'std :: memcpy(data(),src,size()* sizeof(double ))'。另一方面,编译器知道如何优化“std :: vector”和“std :: copy”,而使用'std :: back_inserter'这样的普通类型,例如'double',则很难优化。 – Holt

+0

@FreddyKay另请注意,'QVector ()'可能会预先分配一些容量,所以如果您之后保留,则需要取消分配并重新分配。 – Holt

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

也感谢你。我完全无视这一事实。现在我也更好地理解这一点。 – FreddyKay