2016-07-26 25 views
2

Ich hätte gerne ein Tupel, das ein Array-Element als Mitglied hat. Insbesondere möchte ich, dass dieses Array-Element 2D ist - also muss jede Antwort für mehr als 1D funktionieren. Was ich im Idealfall möchte, ist etwas, das ich mit Initialisierungslisten initialisieren kann, z. std::tuple<ARRAY_TYPE, ...>({{0, 1}, {2, 3}}, ...).Was ist ein einzeiliger Ausdruck für die Konstruktion eines C++ - Tupels mit einem Array-Element (C oder std :: array)?

Es scheint, als ob solch ein Tupel sehr schwer zu konstruieren ist, was eine manuelle Initialisierung erfordert (d. H. Für Schleifen und dergleichen). Hier ist, was ich versucht habe:

std::tuple<int[M][N], ...> - dies funktioniert nicht wegen der Einschränkungen von C-artigen Arrays. Das Tupel selbst ist ein gültiger Typ, aber die Initialisierung muss manuell durchgeführt werden (nicht am Aufbau).

std::tuple<std::array<std::array<int, M>, N>, ...> - Ich dachte, das würde funktionieren, aber aus irgendeinem Grund schlägt etwas wie std::tuple<std::array<std::array<int, 2>, 2>, ...>({{0, 1}, {2, 3}}, ...) mit einem "no matching constructor error" fehl. Es funktioniert jedoch in 1D.

std::tuple<std::vector<std::vector<int>>, ...>({{0, 1}, {2, 3}}, ...) tatsächlich tut Arbeit, aber Vektoren scheinen, wie viel des Guten hier

Alle Gedanken, SO? Gibt es eine Möglichkeit, die C-artigen Arrays zum Funktionieren zu bringen? Das wäre ideal.

+0

[This] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387) kann relevant sein und wird anscheinend in C++ 17 erwartet. – Quentin

Antwort

7

Sie benötigen ein zusätzliches Paar von Klammern {} um das Array:

std::tuple<std::array<std::array<int, 2>, 2>, int> v({{{0, 1}, {2, 3}}}, 1); 
                ^   ^

Dies liegt daran, std::array Aggregat-Initialisierung mit initialisiert wird. Es funktioniert mit std::vector, weil es std::vector<std::initializer_list<T> Konstruktor gibt (hat keine Konstruktoren).

+0

Sie sind natürlich richtig. Upvoted. Ich wünschte immer, C-artige Arrays würden funktionieren. – user2333829

0

Sie können std::make_tuple verwenden, zB:

auto t = std::make_tuple<std::array<std::array<int, 2>, 2>>({{{1, 2}, {3, 4}}}); 

[Bearbeiten] Mein ursprünglicher Vorschlag war:

auto t = std::make_tuple<int[2][2], int>({{1, 2}, {3, 4}}, 42); 

Aber es ist unsicher (erste Tupelelement Speicher stapeln wird zeigen); Siehe Diskussion unten.

+0

Das ist genau was ich will! Und es funktioniert. Aber ist das sicher? Der Rückgabetyp ist 'std :: tuple '. – user2333829

+1

Meine Sorge ist, dass es Zeiger auf die Daten in der std :: initializer_list zurückgibt. – user2333829

+2

@ user2333829 Der innere Typ wird 'int (*) [2]' sein, also ist es nicht sicher - Versuchen Sie einfach, das von einer Funktion oder dem Kopieren eines solchen 'Tupels' zurückzugeben und Sie werden das Problem schnell sehen. – Holt