2016-08-12 98 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