2016-05-13 6 views
0

Ich mache eine Höhenkarte in OpenGL. Die einzige z jedes Vertex in einer Datei gespeichert wird, und ich habe auch den x- und y-Wert in einem Vektor speichern:Wie schiebe ich ein Array in einem Std-Vektor

#include <vector> 
#include <fstream> 
#include <sstream> 

int main(void) 
{ 
    std::vector<float>  _data; 
    float constexpr   triangle_side(1.118033989); 
    std::ifstream   ifs("mymap"); 
    std::string    line; 

    if (not ifs.is_open()) 
     return -1; 
    for (float y(0) ; std::getline(ifs, line) ; --y) 
    { 
     std::istringstream iss(line); 

     for (float x(static_cast<int>(y) % 2 ? 0 : triangle_side/2), z ; iss >> z ; x += triangle_side) 
      _data.push_back({x, y, z}); // does not compile 
    } 
    ifs.close(); 
    return 0; 
} 

Meiner Meinung nach ist es eine schlechte Sache zu tun: _data.push_back(x); _data.push_back(y); _data.push_back(z);, weil die Der Vektor wird vielleicht das Array bei jedem Aufruf neu zuweisen.

Was ist der beste Weg, es zu tun?

Wenn ich tun:

std::vector< std::array<float, 3> > _data; 
//... 
_data.push_back({x, y, z}); 

ist es, die Werte garantiert werden alle zusammenhängend sein?

+0

Wenn Sie die endgültige Größe des Vektors kennen, können Sie 'reserve' http://www.cplusplus.com/reference/vector/vector/reserve/ –

+0

@AlessandroPezzato ich tun nicht wissen, weil die Größe der Karte nicht festgelegt ist. Es hängt von der verwendeten Datei ab. – Boiethios

+0

@Boiethios, ok, so können Sie std :: array oder Joachim antwort (Reserve n + 3 Steckplätze in jeder Schleife) –

Antwort

4

std::array<float, 3> ist wie ein C-Array im Speicher angelegt, so dass die float s benachbart sein wird. Sie könnten nur auch insert verwenden:

_data.insert(_data.cend(), {x, y, z}); 
+0

Wow, das ist cool. Ich schaute in den 'stl_vector.h' und saw: 'iterator insert (const_iterator __position, initializer_list __l)' Es ist eine gute Lösung, und ich frage mich, wie es möglich ist, dass der Standard keine "push_back" (initializer_list __l) ' – Boiethios

+0

@Boietios Sie haben sollte Überprüfen Sie in Zukunft mit cppreference.com. Es ist viel einfacher, als Headerdateien durchzugehen. – Simple

+0

Betrachten Sie emplace_back http://en.cppreference.com/w/cpp/container/vector/emplace_back –

1

Verwenden Sie std :: vector :: reserve (size_type n), um zu reservieren, dass das Hintergrund-Array mindestens n Elemente enthält. Ist dies nicht der Fall, wird es einmal neu zugewiesen. Bei einem bestehenden Vektor, wenn Sie nicht nur '3', sondern 'mindestens 3 weitere' Elemente brauchen, rufen Sie einfach mit (std :: vector :: size + 3) auf. Danach können Sie sicher mit der Garantie zurückschieben, dass das Array nicht innerhalb des Vektors neu zugewiesen wird.

Ein Vektor von std :: array wird gezwungen, durch den Standard zusammenhängend zu sein, wie auch std :: vector. Ein std :: vector von std :: arrays hat somit alle Elemente in zusammenhängender Reihenfolge. Source

@cin_cout: C++ 03 (23.2.4.1):

Die Elemente eines Vektors werden zusammenhängend gespeichert, was bedeutet, dass, wenn v ein Vektor ist wobei T etwas anderen Typ als bool ist , dann gehorcht es der Identität & v [n] == & v [0] + n für alle 0 < = n < v.size().

+0

Ok, danke. Also werde ich diese zweite Lösung verwenden. Ich hatte ein wenig Angst, einen Container mit Containern zu benutzen. Ich denke, es kann zu etwas Chaos führen, das ich nicht verstehen kann ... – Boiethios

+0

Es kann, aber die Speichergarantie ist da. –

Verwandte Themen