2009-07-22 9 views
10

Ist es möglich, auf Werte von Nicht-Typ-Vorlagenparametern in spezialisierten Vorlagenklassen zuzugreifen?Ist es möglich, auf Werte von Nicht-Typ-Vorlagenparametern in spezialisierten Vorlagenklassen zuzugreifen?

Wenn ich Template-Klasse mit Spezialisierung habe:

template <int major, int minor> struct A { 
     void f() { cout << major << endl; } 
    } 

    template <> struct A<4,0> { 
     void f() { cout << ??? << endl; } 
    } 

ich den obigen Fall weiß, ist es einfach, Wert 4 und 0 anstelle der Verwendung von Variablen zu codieren, aber was ich habe eine größere Klasse, die ich spezialisiere und ich möchte auf die Werte zugreifen können.

Ist es möglich, in A < 4,0> auf major und minor Werte (4 und 0) zuzugreifen? Oder muß ich sie auf Vorlage Instanziierung zuweisen als Konstanten:

template <> struct A<4,0> { 
     static const int major = 4; 
     static const int minor = 0; 
     ... 
    } 
+0

Wenn Sie sich auf Werte spezialisieren, dann bedeutet das, dass diese speziellen Werte etwas Besonderes sind. Wenn Sie sie als allgemeine Werte in der gesamten Vorlage verwenden und sie nur an einigen wenigen Stellen als speziell behandeln, kann es sein, dass Sie das spezielle Verhalten in eine kleinere spezialisierte Klassenvorlage abstrahieren können, sodass die große Vorlage vollständig generisch und nicht spezialisiert bleibt. Es ist ein bisschen schwer zu sagen, können Sie Ihre Frage erweitern, um "echter" zu sein? –

+0

Ich denke, die Frage ist wirklich genug. Ich habe eine bestehende Basisklasse, die basierend auf der Protokollversion ein bestimmtes Verhalten implementiert. Zuvor hatte es ein Mitglied, das die Protokollversion zurückgab - da dieses Mitglied nicht mehr verfügbar war, gab es eine Protokollierungsmethode, die die Protokollversion in der Ausgabe enthielt. Ich könnte die Werte einfach fest codieren, aber ich wollte wissen, ob es einen besseren Weg gibt. Die akzeptierte Antwort bietet einen guten Weg, dies zu tun - ich verwende tatsächlich Merkmale in ähnlicher Weise an anderen Orten - um die Parametertypen zu erhalten, aber die Absicht ist die gleiche. – stefanB

Antwort

16

Diese Art von Problem gelöst werden kann durch eine separate Gruppe von "Traits" Strukturen.

// A default Traits class has no information 
template<class T> struct Traits 
{ 
}; 

// A convenient way to get the Traits of the type of a given value without 
// having to explicitly write out the type 
template<typename T> Traits<T> GetTraits(const T&) 
{ 
    return Traits<T>(); 
} 

template <int major, int minor> struct A 
{ 
    void f() 
    { 
     cout << major << endl; 
    } 
}; 

// Specialisation of the traits for any A<int, int> 
template<int N1, int N2> struct Traits<A<N1, N2> > 
{ 
    enum { major = N1, minor = N2 }; 
}; 

template <> struct A<4,0> 
{  
    void f() 
    { 
     cout << GetTraits(*this).major << endl; 
    } 
}; 
+0

+1 schön, danke – stefanB

1

nicht wirklich eine Antwort auf Ihre Frage, aber man kann sich aufzählen, nämlich:

enum{ 
specialisationMajor=4, 
specialisationMinor=0 
}; 

template <> struct A<specialisationMajor,specialisationMinor> { 
    static const int major = specialisationMajor; 
    static const int minor = specialisationMinor; 
    ... 
} 
+0

Ich versuche zu vermeiden, einen anderen Satz von Variablen zu definieren ... das war die Schönheit, diese Template-Parameter zu haben, ich möchte normalerweise nicht auf die Werte zugreifen ... aber vergiss es, aber danke – stefanB

Verwandte Themen