2013-06-03 26 views
6

Erster Teil:Was ist die zugrunde liegende Struktur von std :: initializer_list?

std::initializer_list ist eine wirklich hilfreiche Funktion von ++ 11 C, so fragte ich mich, wie es in der Standard-Bibliothek implementiert. Von dem, was ich here gelesen habe, erstellt der Compiler ein Array vom Typ T und gibt den Zeiger auf initializer_list<T>.

Es gibt auch an, dass das Kopieren eines initializer_list ein neues Objekt erstellt, das auf die gleichen Daten verweist: warum ist es so? Ich hätte gedacht, dass es entweder:

  • kopiert die Daten für die neue initializer_list
  • bewegt sich das Eigentum an den Daten auf den neuen initializer_list

Zweiter Teil:

Schon ab eine von vielen Online-Referenzen für die std::vector Konstruktoren:

vector (initializer_list<value_type> il, 
    const allocator_type& alloc = allocator_type()); 

(6) Initialisiererliste Konstruktors

Konstrukte ein Behälter mit einer Kopie von jedem der Elemente in il, in der gleichen Reihenfolge.

Ich bin mit Bewegung Semantik noch nicht komfortabel, können aber nicht die Daten von il zum vector verschoben werden? Ich bin mir der tiefen Implementierung von std::vector nicht bewusst, aber IIRC verwendet es Plain-Old-Arrays.

+2

Scheint wie ein anderer Grund, cplusplus.com nicht zu vertrauen. Wenn man sich in den Standard begibt, gelangt man schließlich zu der Initialisierer-Liste ctor, die das Paar von Iteratoren ctor aufruft, das (wenn man die Emplace-Konstruktion verwendet) die Elemente wenn möglich verschiebt. – Angew

+6

cplusplus.com ist eine schreckliche, schreckliche Seite, die der C++ - Community Schaden zufügt. Jemand sollte die Server, die ihn hosten, zerschlagen, die Festplatten brennen, sie in Beton einhüllen und sie auf den Grund des Ozeans versenken. –

+1

'Was ist die zugrunde liegende Struktur von std :: initializer_list?' Abstrahiert weg von Ihnen, aus gutem Grund. –

Antwort

12

Was ist die zugrunde liegende Struktur von std::initializer_list?

Höchstwahrscheinlich nur ein Paar Zeiger oder ein Zeiger und eine Größe. Paragraph 18.9/2 des C++ 11 Standard erwähnt auch diese in einer (nicht normativen) Anmerkung:

Ein Objekt des Typs initializer_list<E> ermöglicht den Zugang zu einer Reihe von Objekten des Typs const E. [Hinweis: Ein Paar Zeiger oder ein Zeiger plus eine Länge wäre offensichtlich Darstellungen für initializer_list. initializer_list wird verwendet, um Initialisierungslisten gemäß 8.5.4 zu implementieren. Kopieren ein initializer list tut nicht die zugrunde liegenden Elemente kopieren. -Ende note]

Außerdem:

Ich bin nicht zufrieden mit Bewegung Semantik noch, konnte aber nicht die Daten von il auf den Vektor verschoben werden?

Kein, kann man nicht von den Elementen eines initializer_list bewegen, da Elemente eines initializer_list sollen unveränderlich sein (siehe den ersten Satz des Absatzes oben zitierten). Das ist auch der Grund, warum nur const -qualifizierte Elementfunktionen Ihnen Zugriff auf die Elemente gewähren.

+1

Beachten Sie, dass technisch ein Konstruktor wie 'foo (foo const &&);' ist ein Move-Konstruktor, und würde tatsächlich aufgerufen werden, wenn Sie die Iteratoren einer 'std :: initializer_list 'in' std :: move_iterator 'oder verwendet werden Ein solcher Konstruktor kann nur selten etwas Nützliches (oder anders als ein normaler * Kopie * -Konstruktor) tun. –

+0

@LucDanton: 'foo (foo const &&)' ... ew ... :) Aber ja technisch gesehen hast du recht. Immer noch ändert sich nicht die Tatsache, dass Elemente einer 'initializer_list' unveränderlich sein sollen, so dass" move constructor "nichts bewegen darf, ohne undefiniertes Verhalten zu verursachen. –

+0

@AndyProwl: Eine Initialisierungsliste kann auch Variablenreferenzen enthalten. In diesem Fall verschiebt ein move ctor die Daten des referierten Elements. Also ja, die Liste selbst ist unveränderlich (wird immer die gleiche Referenz enthalten), aber die Verschiebung ctor kann nützlich sein. –

Verwandte Themen