2012-10-11 9 views
6

Betrachten Sie die folgenden vereinfachten Vorlage Meta-Programmiercode, der eine Angle Klasse implementiert, die intern die Modulo 360 Grad reduziert Wert speichert.Auto + statische In-Klasse-Konstante Initialisierung mit Meta-Programmierung

#include <iostream> 
#include <typeinfo> 

template<int N, int D> 
struct Modulus 
{ 
     static auto const value = N % D; 
}; 

template<int N> 
struct Angle 
{ 
     static auto const value = Modulus<N, 360>::value; // ERROR 
     //static int const value = Modulus<N, 360>::value; // OK 
     //static auto const value = N % 360;    // OK 

     typedef Angle<value> type; 
}; 

int main() 
{ 
     std::cout << typeid(Angle<30>::type).name() << "\n"; 
     std::cout << typeid(Angle<390>::type).name() << "\n"; 

     return 0; 
} 

Ausgabe am Ideone

Mit Visual C++ 2010 Express, ich static auto const = Modulus<N, 360>::value tun können, aber mit MinGW gcc 4.7.2 (Nuwen distro) oder Ideone (gcc 4.5.1) Ich muss entweder explizit die Bezeichnung Geben Sie static int const value = Modulus<N, 360>::value ein, oder ich muss mit dem vollen modularen Ausdruck als verwenden.

Frage: Welcher Compiler ist korrekt nach dem neuen C++ 11 Standard?

+0

Ja, in gcc 4.5.1 ist die Unterstützung für C++ 11 immer noch sehr unvollständig, Sie sollten http://gcc.gnu.org/projects/cxx0x.html überprüfen, welche Funktionen in welcher Version verfügbar sind. –

+0

@hvd, falsch. diese müssen als conetexpr deklariert werden. –

+0

@SegFault Ich bekomme diese Fehler auch mit MinGW 4.7 – TemplateRex

Antwort

1

Der Code ist gültig. Visual C++ ist richtig, um es zu akzeptieren und gcc ist falsch, es abzulehnen (zur Vollständigkeit akzeptiert Clang 3.1 auch den Code). Die Beschreibung besagt, dass (C 11 ++ 7.1.6.4 [dcl.spec.auto]/4):

Der autoTyp-Spezifizierer ... kann auch ein statisches Daten verwendet wird Element in Schlußes mit Eine Klammer-oder-Gleich-Initialisierer, die innerhalb der Member-Spezifikation einer Klassendefinition angezeigt wird.

Ihr value ist ein statisches Datenelement. Es hat eine Klammer-oder-gleich-Initialisierer (das ist der = Modulus<N, 360>::value Teil der Deklaration), und der Initialisierer erscheint innerhalb der Mitglieder-Spezifikation der Klassendefinition (dh es ist, was Sterblichen einen "Inline-Initialisierer" nennen könnte ").

+0

+1 und akzeptiert. Danke vielmals! Was ist der beste Weg, um einen Fehlerbericht zu erstellen? – TemplateRex

+0

@rhalbersma: GCC hat [eine Bugzilla-Datenbank] (http://gcc.gnu.org/bugzilla/). Ich kenne ihre Fehlermeldeverfahren jedoch nicht. Ich würde empfehlen, zuerst zu suchen, um zu sehen, ob dies bereits gemeldet wurde. –

Verwandte Themen