Was ist die richtige Methode zum initialisieren eines Mitglieds-array mit einer Initialisierer-Liste?
Ich habe eine struct
hält, dass ein array, und ich möchte, um eine Initialisierungsliste um die struct-Konstruktor weitergeleitet werden, auf dem array. Um zu veranschaulichen, habe ich versucht:
#include <initializer_list>
struct Vector
{
float v[3];
Vector(std::initializer_list<float> values) : v{values} {}
};
int main()
{
Vector v = {1, 2, 3};
}
Die zu dem Fehler geführt haben:
error: cannot convert ‘std::initializer_list<float>’ to ‘float’ in initialization
Ich habe versucht, mit Klammern, statt der geschweiften Klammern für v
aber das gab die Fehlermeldung:
error: incompatible types in assignment of ‘std::initializer_list<float>’ to ‘float [3]’
Meine Haupt-motivation für den Versuch, dies zu tun ist zu vermeiden, wird die folgende Warnung, dass das Geräusch erzeugt:
template <int N>
struct Vector
{
float v[N];
};
template <>
struct Vector<2>
{
float x, y;
};
int main()
{
Vector<2> v2 = {1.0f, 2.0f}; //Yay, works
Vector<3> v3 = {1.0f, 2.0f, 3.0f}; //Results in warning in clang++
Vector<3> u3 = {{1.0f, 2.0f, 3.0f}}; //Must use two braces to avoid warning
//If I could make Vector<N> take an initializer list in its constructor, I
//could forward that on to the member array and avoid using the double braces
}
warning: suggest braces around initialization of subobject
Also meine Frage ist: Wie kann ich die initialisieren Mitglied array mit einer Initialisierer-Liste? (also Wie kann ich den ersten code arbeiten? Oder ist es nicht möglich?
- Für ein Aggregat, das Sie benötigen würde nicht einmal ein Tor. Hinweis: die Größe eines
initializer_list
ist variabel. Es gibt auch einen Unterschied zwischen Initialisierung mit eineminitializer-list
und Liste-Initialisierung (das ist ein sprachkonstrukt und kann dazu führen, ruft ein Tor mit einer Initialisierer-Liste). - Sie können das nicht wirklich tun, aber könnten Sie verwenden ein
std::array
statt? - Er könnte std::array, aber ich lese dies als eine Frage der Sprache, nicht der standard-Bibliothek. Und, mit allem Respekt wem auch immer, sagen, jemand zu gehen, Lesen Sie die standard-Bibliothek zu erzählen ist wie ein Kleinkind, Englisch zu lernen durch die Lektüre von Shakespeare. Also std::array ist das nicht ein sehr gute Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Ihre Klasse ist ein Aggregat, die Sie verwenden können, Ihre syntax
Hinweis: dies ist möglich, da die Klammer-elision. Keine Notwendigkeit für
v = {{1,2,3}};
obwohl dies auch möglich. Clang Fragen diese Warnung, weil die übersichtlicher und weniger fehleranfällig syntax mit doppelten geschweiften Klammern (einer für die Initialisierungv
und eine für die Initialisierung des sub-Aggregatelems
).Wenn Ihre Klasse ist nicht ein Aggregat, die Sie verwenden können, variadic templates:
Einfache C-style-arrays sind nicht abtretbar. Wenn Sie die Umschaltung auf die Verwendung
std::array
statt, die Initialisierung wird trivial.std::array
. Es ermöglicht eine wesentlich bessere syntax für die Initialisierung.Versuchen
std::copy
.Initialisieren ein array nicht-statische member, verwenden Sie die syntax Aggregat. Das heißt, direkt füllen, verspannt-Liste mit
N
Elemente, wo N wird die Anzahl der Elemente im array. Sie können weniger als N wenn der Elementtyp Standard-Baubar; die fehlenden Elemente werden mit dem Wert initialisiert wird.Es ist keine Konvertierung von einem
std::initializer_list
zu einem array. Auch wenn Sie eine Quelle geben könnte, zu konvertieren, um eine array-Referenz (nicht den Wert), Sie konnte es nicht ausnutzen, die Umwandlung in eine member-Initialisierung da arrays sind nicht Abtretbar. In diesen Fällen müssen Sie etwas verwenden wiestd::copy
innerhalb des Konstruktors Körper.Hinweis für mehrdimensionale arrays, da arrays sind nicht Übertragbar, verwenden Sie nur verspannt-Listen zur Darstellung der sub-arrays. Es gibt auch die Möglichkeit der Klammer elision; mit einer flachen Liste von
std::remove_all_extents<TheArrayType>::type
Elemente und die compiler machen-tun. (Wenn die innere nicht-array-Typ ist ein built-in-character-Typ, können Sie manchmal eine Zeichenfolge in Anführungszeichen als das nächste-zu-innerste-Initialisierer für ein mehrdimensionales array.)