2016-04-29 25 views
1

Dies ist der Code:Visual Studio 2015 Zeichenfolgenliteral nicht immer konstant?

#include <iostream> 
using namespace std; 

struct ConstStr 
{ 
    char const* const Str; 
    constexpr struct ConstStr(char const* str) :Str(str) {} 
}; 

struct Container { 
    static constexpr struct ConstStr hey{ "hey" }; 
}; 


struct StructScope1 
{ 
    struct ConstStr { 
     char const* const Str; 
     constexpr ConstStr(char const* str) :Str(str) {} 
    }; 
    struct Container { 
     static constexpr StructScope1::ConstStr hey{ "hey" }; 
    }; 
}; 

struct StructScope2 
{ 
    struct Container { 
     static constexpr ConstStr hey{ "hey" }; 
    }; 
}; 

struct Container2 { 
    static constexpr struct StructScope1::ConstStr hey { "hey" }; 
}; 

int main() 
{ 
    cout << "Hello World" << endl; 
    cout << "Container::hey.Str " << Container::hey.Str << endl; 
    cout << "StructScope1::Container::hey.Str " << StructScope1::Container::hey.Str << endl; 
    cout << "StructScope2::Container::hey.Str " << StructScope2::Container::hey.Str << endl; 
    cout << "Container2::hey.Str " << Container2::hey.Str << endl; 
} 

ich Visual Studio 2015. Aus irgendeinem Grund bin mit, schlägt die Erklärung/Initialisierung von StructScope1::Container::hey zu kompilieren. Es gibt dem Fehler

Ausdruck einen konstanten Wert

Aber ich initialisieren den gleichen Code in anderen Orten haben muss, und es funktioniert gut. Ist das ein Compiler Bug, oder fehlt mir etwas?

+0

"_in andere places_" Wie, was oder wo? –

Antwort

1

Ich denke, es ist irreführende Compile-Fehlermeldung.

Dies funktioniert:

struct StructScope1 
{ 
    struct ConstStr { 
     char const* const Str; 
     constexpr ConstStr(char const* str) :Str(str) {} 
    }; 
    struct Container; 
}; 

struct StructScope1::Container{ 
    static constexpr StructScope1::ConstStr hey{ "hey" }; 
}; 

Wenn ich die verschachtelte Klasse außerhalb definieren, die hey versucht vor dem Konstruktor definiert werden (der Konstruktor muss die bereits errichteten hey von Standardregeln sehen).

Clang ist etwas klar:

a.cpp:23:49: error: constexpr variable 'hey' must be initialized by a constant expression 
    static constexpr StructScope1::ConstStr hey{ "hey" }; 
              ^~~~~~~~~~~~ 
a.cpp:23:49: note: undefined constructor 'ConstStr' cannot be used in a constant expression 
a.cpp:20:19: note: declared here constexpr ConstStr(char const* str) :Str(str) {} 
+0

Ich glaube ich verstehe was du sagst. Wenn StructScope1 :: Container in StructScope1 definiert ist und StructScope1 :: ConstStr in StructScope1 definiert ist, wird StructScope1 :: Container :: hey vor StructScope1 :: ConstStr :: ConstStr (dem Konstruktor) definiert. Also versucht er, diesen Destruktor zu benutzen, bevor er definiert ist. Ist das korrekt? – user1646801

+0

Ich meine Konstruktor, nicht Destruktor. Anscheinend kann ich meinen Kommentar nicht bearbeiten, um das zu beheben. – user1646801

+0

@user Sie können jedoch einen neuen Kommentar löschen und schreiben. ;; Ja, das wäre meine Beobachtung. Ich werde eine Erklärung hinterlassen, warum das einem Spec-Guru passiert. Meine Interpretation ist, dass statische Mitglieder vor Konstruktoren definiert sind, zu dem Zweck, dass der Konstruktor sie möglicherweise verwenden muss (das heißt, 'hey' sehen nur eine Deklaration, wenn sie definiert ist); Obwohl es auf meinem VS2015 abstürzt, ist es wahrscheinlich nicht sicher (funktioniert gut mit clang) – krOoze