2013-05-15 24 views
5

Mam tablicę w stylu C i chcę ją przypisać do QVectora. Gdybym użyciu std :: vector, użyłbym assign():std :: wektor :: przypisz odpowiednik QVector

int arr[] = { 1, 2, 3, 4, 5 }; 
std::vector<int> v; 
v.assign(arr, arr + sizeof(arr)/sizeof(int)); 

Ale QVector nie mogłem znaleźć podobnego assign() metody lub każdy konstruktor zakres przyjmujących.

Już zakodowałem pętlę for, aby to zrobić, ale byłem zaskoczony, że nie ma tak podstawowej funkcji, czy to naprawdę tak, czy jest odpowiednik?

+0

Tak jak na marginesie, w twoim przykładzie nie użyłbym nawet 'assign', ale' vector'. –

Odpowiedz

5

Można użyć Qt qCopy():

int arr[] = { 1, 2, 3, 4, 5 }; 
QVector<int> v(5); 
qCopy(arr, arr+5, v.begin()); 

Albo można użyć std::copy() oczywiście.

int arr[] = { 1, 2, 3, 4, 5 }; 
QVector<int> v(5); 
std::copy_n(&arr, 5, v.begin()); 
// or more general: 
QVector<int> v2; 
std::copy(std::begin(arr), std::end(arr), std::back_inserter(v2)); 
// without begin/end 
std::copy(arr, arr + 5, std::back_inserter(v2)); 
+0

@ pmr Ładne, dużo lepkie. – cmannett85

+2

Nie ma tego samego efektu. Popycha nowe elementy z tyłu. Działa tylko wtedy, gdy 'QVector' jest pusty. – juanchopanza

+0

@juanchopanza Ma taki sam efekt, jak kod oparty na wektorze, który jest replikowany przez OP, ale masz rację co do zasady. – cmannett85

1

Jest fromStdVector(), który pozwala na stworzenie QVector z std::vector:

int arr[] = { 1, 2, 3, 4, 5 }; 
std::vector<int> v; 
v.assign(arr, arr + sizeof(arr)/sizeof(arr[0])); 
QVector<int> qvec = QVector<int>::fromStdVector(v); 
+0

Nie sądzę, że właśnie tego chce OP. Chce przypisać tablicę stylu C do 'QVector'. On nie chce przypisać 'wektora' do' QVector'. – pmr

+0

Jedynym problemem jest to, że tworzymy i niszczymy obiekt tymczasowy (tj. Wydajność). – sashoalm

+0

@pmr Chociaż konwersja tablicy na 'std :: vector' mogłaby nastąpić po konwersji z' std :: vector' na 'QVector', ale zgadzam się, że jest to prawdopodobnie gorsze od prostego' std :: copy' (szczególnie w odniesieniu do wydajności). Ale w ten sposób można to zrobić tylko w jednej pojedynczej linii inicjującej, zamiast inicjalizacji, po której następuje kopiowanie (oczywiście tylko wtedy, gdy upuszcza się całe to '' '' 'szaleństwo dla poprawnie zainicjalizowanego tymczasowego' std :: vector'). –

-2

dla typów prostych (np int, char, void * ... itd), można wziąć przewagę :: memcpy

int arr[] = { 1, 2, 3, 4, 5 }; 

const int CNT = sizeof(arr)/sizeof(int); 
QVector<int> v(CNT); 

// memcpy may be faster than std::copy_n in some compiler 
::memcpy(v.data(), arr, CNT * sizeof(int)); 

dla obiektów (np std :: string), napisać pętlę do kopiowania obiektów z arr v

potem po prostu powołać kopiowaniem konstruktorzy jeden po drugim

np

std::string arr[] = { std::string("a"), std::string("b"), std::string("c") }; 
const int CNT = sizeof(arr)/sizeof(std::string); 
QVector<std::string> v(CNT); 
for(size_t i = 0; i < CNT ; ++i) 
    v[i] = arr[i]; 

jako konstruktora kopia dla każdego obiektu w ARR muszą być wywołana jeden po drugim, jestem pewien, że nie będzie to szybsze rozwiązanie (nawet użyć std :: kopię()).

Powyższy kod może powodować mniejszy rozmiar kodu w porównaniu do std :: copy w niektórych kompilatorach.

+0

memcpy nie działałby na wektor std :: stringów. Ten kod może prowadzić do potencjalnych błędów. – sashoalm

+3

To jest obrzydliwość. – pmr

+1

* Nigdy * nie używaj niczego podobnego do memsetu w klasie kontenera C++. Po prostu nie rób tego. –