2016-04-19 7 views
2

ich eine Klasse sorta habe wie zu füllen Versuch:(VS2015) eine statische Karte mit Daten aus Initialisiererliste

class Object { 
public: 
    struct Flag { 
     const uint32_t bit = 0; 
     const wchar_t* name = L""; 
     const wchar_t sign = L""; 
    } 

    static std::map<const char*, Flag> Flags; 
} 

Ich bin zur Zeit auf VS2015, will aber Klirren und gcc (die neuesten) unterstützen. Mein Problem ist, ich kann nicht herausfinden, wie man diese Karte tatsächlich mit Daten initialisiert.

Ich versuchte es inline setzen, wie:

static std::map<const char*, Flag> Flags = { 
    { "FOO1",  { 0, L"FOO1",  L'A' } }, 
    { "FOO2",  { 1, L"FOO3",  L'B' } }, 
    { "FOO3",  { 2, L"FOO3",  L'C' } } 
} 

Aber das darüber beschwert, dass nur const ganzzahligen Typen in-Klasse sein kann. Okay! Also ließ ich es ebenso wie die Deklaration in der Klassendefinition (wie im ersten Codeausschnitt gezeigt) und setzen diese in der zugehörigen cav:

static std::map<const char*, Object::Flag> Object::Flags = { 
    { "FOO1",  { 0, L"FOO1",  L'A' } }, 
    { "FOO2",  { 1, L"FOO3",  L'B' } }, 
    { "FOO3",  { 2, L"FOO3",  L'C' } } 
} 

Nun beklagt dies:

error C2440: 'initializing': cannot convert from 'initializer list' to 'std::map,std::allocator>>'

Die Ding ist, ich könnte haben geschworen Ich hatte dies funktioniert, so denke ich, ich muss die Syntax falsch haben. Wenn nicht, vermisse ich eindeutig, wie man eine statische Map in einen Klassen-Namespace lädt.

Antwort

3

Nach dem C++ 11 Standard ist Flag kein Aggregat aufgrund th Das Vorhandensein der Klammer-oder-Gleich-Initialisierer (aka Standardmemberinitialisierer), so versucht, Aggregat Initialisierung zu verwenden, um es zu initialisieren fehlschlägt. C++ 14 removed this restriction, so wird Flag als ein Aggregat gemäß dieser Version des Standards und your code is valid betrachtet.

Hier ist eine viel einfachere Version Ihres Beispiels, die mit -std=c++11 kompiliert, aber erfolgreich kompiliert mit -std=c++14.

Live demo.

VS2015 hat immer noch das Verhalten von C++ 11, also entfernen Sie entweder die standardmäßigen Elementinitialisierer (wodurch Flag ein Aggregat wird), oder stellen Sie einen Konstruktor für Object::Flag bereit.

6

Sie können ein Objekt von Object::Flag nicht initialisieren, indem Sie die Listeninitialisierungssyntax { 0, L"FOO1", L'A' } verwenden, da es Standardelementinitialisierer hat. Weitere Informationen finden Sie unter http://en.cppreference.com/w/cpp/language/list_initialization.

Sie können nicht Aggregat Initialisierung des Formulars

Object::Flag f = { 0, L"FOO1", L'A'}; 

aus dem gleichen Grund. Siehe http://en.cppreference.com/w/cpp/language/aggregate_initialization.

ändern Object::Flag die einfacheren Form:

struct Flag { 
    const uint32_t bit; 
    const wchar_t* name; 
    const wchar_t sign; 
}; 

und dann sollten Sie in der Lage sein zu verwenden:

std::map<const char*, Object::Flag> Object::Flags = { 
    { "FOO1", { 0, L"FOO1", L'A' } }, 
    { "FOO2", { 1, L"FOO3", L'B' } }, 
    { "FOO3", { 2, L"FOO3", L'C' } }}; 

Danach sollten Sie in der Lage sein, auch verwenden, um:

Object::Flag f = { 0, L"FOO1", L'A'}; 
+0

Das stimmt nicht mehr mit C++ 14 Ich denke (sieht aus wie VS ist ein bisschen spät). – Holt

+0

@Holt, das ist gut zu wissen. Danke für die Köpfe hoch. –

+0

Dieser Link kann ergänzen Sie denke ich: http://en.cppreference.com/w/cpp/language/aggregate_initialization – Holt

Verwandte Themen