2016-08-10 5 views
1

Es sieht aus wie Compiler akzeptieren unterschiedliche Syntax zur Initialisierung von statischen in Vorlage.Template-Spezialisierung statische Initialisierung ICC + Vc vs GCC + Clang

template <typename T> struct TBase 
{ 
    static const int i; 
    static const int j; 
}; 

// compile: gcc + clang + visual + icc 
template <> const int TBase<double>::i=1; 

// compile: vc + icc 
// failed gcc, gcc -fpermissive, clang 
const int TBase<double>::j=2; 

Ist die Syntax ohne template<> von der Norm akzeptiert, auch wenn es im Moment offensichtlich nicht tragbar ist?

bearbeiten: Mit diesem Code auf VC++ TBase<double>::i==1 und TBase<double>::j==2 genau wie der Code ohne Vorlage.

struct noTemplate 
{ 
    static const int i; 
    static const int j; 
}; 
const int noTemplate::i=1; 
const int noTemplate::j=2; 

gcc und Klirren scheint die Verwendung von template<> zur Durchsetzung dieser statisch zu initialisieren, ich sehe nicht, warum Compiler diese Informationen benötigen.

Antwort

3

Die beiden Syntaxen sind beide gültig, aber sie bedeuten verschiedene Dinge. Die Syntax mit template<> wird verwendet, um zu erklären oder zu definieren, ein Mitglied einer impliziten oder expliziten Instanziierung: ist

template<class T> struct X { static int const i; }; 

template<> int const X<char>::i = 1; // Define member of an implicit instantiation 

template struct X<long>; 
template<> int const X<long>::i = 2; // Define member of an explicit instantiation 

Die Syntax ohne template<> verwendet, um ein Mitglied einer Spezialisierung zu definieren:

template<> struct X<float> { static int const j; }; // Class template specialization 
int const X<float>::j = 3; 
+0

Danke. Implizite Instanziierung ist also für die lokale Verwendung von Vorlagen, explizite Instanziierung für den Export von Vorlagen wie in lib. Mit vC++ die Template Deklaration und Initialisierung eines Wertes wie int const X :: j = 3; ist genug für Code (x ()). j zu sein "gültig" scheint ein bisschen seltsam. – ColdCat

0

Ja, es scheint Standard zu erfüllen.

Mindestens C++ 14 Standard enthält (hoffe seine letzte Revision enthält es auch, ich habe mit Pre-Release-Version überprüft http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf).

14.7.1 Implizite Instanziierung ... Es sei denn, ein Mitglied einer Klasse-Vorlage oder ein Mitglied Vorlage wurde explizit instanziiert oder explizit spezialisiert, die Spezialisierung des Mitglieds implizit instanziiert wird, wenn die Spezialisierung auf ein referenziert Kontext, der die Definition des Members erfordert; insbesondere tritt die Initialisierung (und alle damit verbundenen Nebenwirkungen) eines statischen Datenelements nicht auf, es sei denn, das statische Datenelement selbst wird in einer Weise verwendet, die erfordert, dass die Definition des statischen Datenelements existiert. ...

von const int TBase<double>::j=0; Sie zugreifen (spezialisiert nicht) statisches Element j von TBase<double>, so sollte TBase<double> Spezialisierung erstellt werden, wenn noch nicht vorhanden ist.

Das Codebeispiel ohne Vorlagen, die, die Sie gerade struct Mitglied zugreifen, beweist:

struct WithoutTemplate { 
    static const int i; 
}; 
const int WithoutTemplate::i = 5; 
+0

Danke, ich habe meine Frage aktualisiert, um meine Fragen zu unterstreichen. – ColdCat

Verwandte Themen