constexpr initialisiert statisches Element mit statischer Funktion

Bedarf

ich will einconstexpr Wert (d. h. eine Kompilierzeitkonstante) berechnet aus aconstexpr Funktion. Ich möchte, dass beide Bereiche auf den Namespace einer Klasse beschränkt sind, d. H. Eine statische Methode und ein statisches Mitglied der Klasse.

Erster Versuch

Ich schrieb dies zuerst auf (für mich) offensichtliche Weise:

class C1 {
  constexpr static int foo(int x) { return x + 1; }
  constexpr static int bar = foo(sizeof(int));
};

g++-4.5.3 -std=gnu++0x sagt dazu:

error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression

g++-4.6.3 -std=gnu++0x beschwert sich:

error: field initializer is not constant
Zweiter Versuch

OK, dachte ich, vielleicht muss ich die Dinge aus dem Klassenkörper entfernen. Also habe ich folgendes versucht:

class C2 {
  constexpr static int foo(int x) { return x + 1; }
  constexpr static int bar;
};
constexpr int C2::bar = C2::foo(sizeof(int));

g++-4.5.3 werde das ohne beschwerden zusammenstellen. Leider verwendet mein anderer Code einen bereichsbasierten Codefor Loops, also muss ich mindestens 4.6 haben. Nun, da ich mir das genauer anseheSupport-Liste, anscheinendconstexpr würde auch 4.6 erfordern. Und mitg++-4.6.3 Ich bekomme

3:24: error: constexpr static data member ‘bar’ must have an initializer
5:19: error: redeclaration ‘C2::bar’ differs in ‘constexpr’
3:24: error: from previous declaration ‘C2::bar’
5:19: error: ‘C2::bar’ declared ‘constexpr’ outside its class
5:19: error: declaration of ‘const int C2::bar’ outside of class is not definition [-fpermissive]

Das klingt wirklich komisch für mich. Wie unterscheiden sich die Dinge?constexpr" Hier? Ich habe keine Lust hinzuzufügen-fpermissive da ich es vorziehe, wenn mein anderer Code genauestens überprüft wird. Bewegen derfoo Die Implementierung außerhalb des Klassenkörpers hatte keine sichtbaren Auswirkungen.

Erwartete Antworten

Kann mir jemand erklären, was hier los ist? Wie kann ich erreichen, was ich versuche zu tun? Ich interessiere mich hauptsächlich für Antworten der folgenden Arten:

Eine Möglichkeit, dies in gcc-4.6 zum Laufen zu bringenEine Beobachtung, dass spätere gcc-Versionen mit einer der Versionen korrekt umgehen könnenEin Zeiger auf die Spezifikation, nach der mindestens eines meiner Konstrukte erstellt wurdesollte arbeiten, damit ich die gcc-Entwickler daran hindern kann, es tatsächlich zum Laufen zu bringenInformationen, die ich möchte, sind nach den Spezifikationen nicht möglich, vorzugsweise mit einigen Hinweisen auf die Gründe für diese Einschränkung

Andere nützliche Antworten sind ebenfalls willkommen, werden aber möglicherweise nicht so einfach akzeptiert.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage