2017-10-31 16 views
0

Ich habe eine Klasse, die einen Skalar zusammen mit zugehörigen physikalischen Dimension Exponenten speichert:Wie verwende ich eine Template-Klasse als Template-Parameter?

template <int L, int M, int T, int C, int K, int S, int I> 
class Dimension<L, M, T, C, K, S, I> 
{ 
    ... 
} 

Ich mag würde einen Vektor wie Klasse (Vec) mit statischen Speicher bauen, die eine Anordnung dieser Objekte speichert. würde ich die Vec Klassenvorlage vermutet etwas aussehen würde:

template <Dimension<L, M, T, C, K, S, I> D, size_t N> 
class Vec 
{ 
    ... 
} 

Aber dies bewirkt, dass ein Fehler als Template-Parameter D auf Template-Parametern abhängig (L, M, T, C, K, S, I). Ich habe ein paar Dinge mit roher Gewalt versucht, aber ich rate nur und würde es vorziehen, von jemandem mit Sachverstand in der Sache die richtige Methode gezeigt zu bekommen.

Ich habe Beispiele gesehen, wo template<class> in die Vorlage Argumente eingefügt wird, aber ich verstehe nicht ganz, was es erreicht oder sogar, wenn es tatsächlich anwendbar ist. Vielen Dank für Ihre Hilfe.

Beachten Sie, dass mir bewusst ist, dass diese Klassenbeispiele bereits früher implementiert wurden, wahrscheinlich in besserer Weise.

Bearbeiten: Ein Tippfehler korrigiert und Name der Vec-Klasse geändert.

+0

Haben Sie ['std :: array'] (http://en.cppreference.com/w/cpp/container/array) angeschaut? –

+0

Wie gesagt, ich weiß, dass so etwas gemacht wurde (zum Beispiel std :: array und nicht diese Vektorklasse), aber ich bin daran interessiert, mein eigenes zu bauen. Ich möchte ausdrücklich, dass die gespeicherte Klasse auf einen Typ der Dimension <> und nicht auf irgendeine Klasse T beschränkt ist. – Arc

Antwort

1

Wenn ich richtig verstehe, brauchen Sie template template Argumente.

Wie dem auch sei, zunächst einmal daran erinnern, das Wort zu verwenden struct (oder class) für Dimension

template <int L, int M, int T, int C, int K, int S, int I> 
struct Dimension 
{ }; 

Zweitens können Sie einen Typ vect erklären (bitte nicht vector, dass mit dem Standard std::vector kollidieren können) wie folgt

template <typename, std::size_t> 
struct vect; 

als empfangen einen Typ und eine vorzeichenlose Ganzzahl.

Dann können Sie eine partielle Spezialisierung (mit std::cout exaple für die Vorlage Integer-Werte) implementieren als

template <template <int, int, int, int, int, int, int> class Dim, 
     int L, int M, int T, int C, int K, int S, int I, std::size_t N> 
struct vect<Dim<L, M, T, C, K, S, I>, N> 
{ 
    vect() 
    { std::cout << " - L: " << L << " - M: " << M << " - T: " << T 
       << " - C: " << C << " - K: " << K << " - S: " << S 
       << " - I: " << I << " - N: " << N << std::endl; } 
}; 

folgt können Sie diese vect verwenden als

vect<Dimension<2, 3, 5, 7, 11, 13, 17>, 42> v; 

mit C Dies funktioniert folgendermaßen ++ 98 auch.

Wenn Sie C++ 11 oder höher verwenden, können Sie variadische Argumente verwenden, damit die vect Spezialisierung vereinfacht werden kann (ein wenig) wie folgt

template <template <int...> class Dim, 
     int L, int M, int T, int C, int K, int S, int I, std::size_t N> 
struct vect<Dim<L, M, T, C, K, S, I>, N> 
{ /* ... */ }; 

oder variadische Argumente verwenden, ein wenig mehr

aber in diesem Fall ist es ein wenig komplizierter, die einzelnen Is... Werte zu verwenden.

Aber, wenn Sie mindestens C++ 11 verwenden können, ich stark schlagen Sie vor (nach dem Beispiel von Miles Budnek) die Verwendung von std::array.

+0

Vielen Dank für Ihre Erklärung, die Argumente der "Template-Vorlage" machen jetzt viel mehr Sinn! – Arc

+0

@Arc - ein kleiner Vorschlag hinzugefügt. – max66

Verwandte Themen