2012-10-11 7 views
6

Considerare il seguente codice di meta-programmazione modello semplificato che implementa una classe Angle che memorizza internamente il modulo a 360 gradi di valore ridotto.Initalization costante in classe Auto + statico con meta-programmazione

#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; 
} 

Uscita su Ideone

Con Visual C++ 2010 Express, che posso fare static auto const = Modulus<N, 360>::value, ma con MinGW gcc 4.7.2 (Nuwen distro) o Ideone (gcc 4.5.1) devo né indicare esplicitamente la digitare come static int const value = Modulus<N, 360>::value o devo utilizzare auto con l'espressione modulare completa come static auto const value = N % 360;.

Domanda: quale compilatore è corretto in base al nuovo standard C++ 11?

+0

Sì, in gcc 4.5.1 il supporto per C++ 11 è ancora molto incompleto, è necessario controllare http://gcc.gnu.org/projects/cxx0x.html per vedere quali funzionalità sono disponibili in quale versione. –

+0

@hvd, errato. quelli devono essere dichiarati constexpr. –

+0

@SegFault Ricevo anche questi errori con MinGW 4.7 – TemplateRex

risposta

1

Il codice è valido. Visual C++ ha ragione ad accettarlo e gcc è sbagliato a rifiutarlo (per completezza, Clang 3.1 accetta anche il codice). La specifica stabilisce che (C++ 11 7.1.6.4 [dcl.spec.auto]/4):

il autotipo specificatore può essere utilizzato anche in ... dichiarare un membro dati statico con a inizializzatore brace-or-equal- visualizzato all'interno della specifica membro di una definizione di classe.

Il value è un membro di dati statici. Ha un iniziatore iniziatore o uguale (ovvero la parte = Modulus<N, 360>::value della dichiarazione) e l'inizializzatore appare all'interno della specifica membro della definizione di classe (ovvero, è ciò che i mortali potrebbero chiamare un "inizializzatore in linea" ").

+0

+1 e accettato. Molte grazie! Qual è il modo più appropriato per presentare una segnalazione di bug? – TemplateRex

+0

@rhalbersma: GCC ha [un database Bugzilla] (http://gcc.gnu.org/bugzilla/). Non ho familiarità con le loro procedure di segnalazione dei bug, però. Consiglierei di cercare prima per vedere se questo è già stato segnalato. –

Problemi correlati