2016-08-12 160 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のメカニズムのいくつかの種類を破るだろうか?今、私はこのようにそれを行うために

あなたはvec.data()に割り当てることができませんので

+0

答えはありませんが、 'foo'がポインタとサイズの代わりにdoublesのstd :: vectorを受け取ると、より簡単で簡単になります。 'void foo(const std :: vector &receivedArray){...}'。その場合、必要なのは 'QVector :: fromStdVector'だけです。 – Elijan9

+0

合意しましたが、これは私の責任ではありません。それが実際にQVectorのポイントです。私はsize_tを使ってfloat *を受け取って生きなければなりません。これは別のAPIから来ていて、そうでなければ自分のプログラムでmorの高度な型を使いたいからです。 – FreddyKay

答えて

2

最初のものは、不必要な作業を行い、初期化デフォルトで構築されたベクトルは、それを満たす前に2倍になります。あなたはアルゴリズムに頼らなければならないので、残念ながら、QVectorは、遠隔挿入を欠い:data()あなたは左側に置くことができない右辺値であるT *を返すよう

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)); 
} 

番目のバージョンでも、コンパイルされません。割り当ての側

+1

私はreserveとback_inserterで奇妙な問題がありました。私はGBの範囲でかなり大きな配列で上記の関数を何度もやらなければなりません。私は、QVector :: reserveの後にQVector :: resizeが続いて、単純なコピーを行い、イテレータがback_inserterよりも速く(約50%)動作するという観測を行いました。あなたは似たような行動を覚えていますか? – FreddyKay

+1

@FreddyKayはい、この特定のケースではおそらく2つの理由であなたのバージョンを使用するほうが速いでしょう:1) 'std :: vector {'}を '0'で初期化するのは、' std :: memset 2)単純な型のコピーは、 'std :: memcpy(data()、src、size()* sizeof(double()、0、size()* sizeof )) ')。コンパイラは 'std :: back_inserter'を使って' std :: vector'と 'std :: copy'を' double'のような単純な型のために最適化する方法を知っています。 – Holt

+0

@FreddyKayまた、 'QVector ()'は容量をあらかじめ割り当てている可能性があるので、後で予約する場合は、割り当てを解除してから再割り当てする必要があります。 – Holt

1

QVector::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