Wie erstelle ich eine Vorlagenfunktion innerhalb einer Klasse? (C ++)


144

Ich weiß, dass es möglich ist, eine Vorlagenfunktion zu erstellen:

template<typename T>
void DoSomeThing(T x){}

und es ist möglich, eine Vorlagenklasse zu erstellen:

template<typename T>
class Object
{
public:
    int x;
};

Aber ist es möglich, eine Klasse nicht innerhalb einer Vorlage zu machen und dann eine Funktion in dieser Klasse zu einer Vorlage zu machen? Dh:

//I have no idea if this is right, this is just how I think it would look
class Object
{
public:
    template<class T>
    void DoX(){}
};

oder etwas in dem Maße, in dem die Klasse nicht Teil einer Vorlage ist, sondern die Funktion?

Antworten:


115

Ihre Vermutung ist die richtige. Das einzige, woran Sie denken müssen, ist, dass sich die Definition der Elementfunktionsvorlage (zusätzlich zur Deklaration) in der Header-Datei und nicht in der CPP befinden sollte, obwohl sie sich nicht im Hauptteil der Klassendeklaration selbst befinden muss.


3
Und auch, dass man sie nicht spezialisieren kann. :-(
— Frank Krueger

7
Nicht genau richtig. Die Definition kann sich in einer CPP-Datei befinden, sofern sie für jeden eindeutigen Vorlagenparameter n-uplet von einer Nicht-Vorlagenfunktion / -methode nach ihrer Definition einmal aufgerufen wird.
— Benoît

1
Daher ist mein "sollte" - es in der Kopfzeile zu halten, der einfachste Weg, dies zu erreichen.
— Nicht sicher

4
Eigentlich glaube ich, dass Sie sie explizit spezialisieren können, aber Sie können sie nicht teilweise spezialisieren. Leider weiß ich nicht, ob dies eine compilerspezifische Erweiterung oder ein C ++ - Standard ist.
— Patrick Johnmeyer

7
Es ist eigentlich Standard C ++. Sie können struct A {template <typename> void f () ausführen. }; template <> void A :: f <int> () {} zum Beispiel. Sie können sie einfach nicht auf den Klassenbereich spezialisieren, aber Sie können dies gut tun, wenn Sie dies im Namespace-Bereich tun. (Nicht zu verwechseln mit dem Bereich, in den die Spezialisierung tatsächlich eingefügt wird: Die Spezialisierung bleibt weiterhin Mitglied der Klasse - ihre Definition erfolgt jedoch im Namespace-Bereich. Oft entspricht der Bereich, in den etwas eingefügt wird, dem Bereich etwas ist definiert bei - aber das ist manchmal nicht wahr, wie in allen Fällen von Definitionen außerhalb der Klasse)
— Johannes Schaub - litb

70

Siehe hier: Vorlagen , Vorlagenmethoden , Elementvorlagen, Elementfunktionsvorlagen

class   Vector
{
  int     array[3];

  template <class TVECTOR2> 
  void  eqAdd(TVECTOR2 v2);
};

template <class TVECTOR2>
void    Vector::eqAdd(TVECTOR2 a2)
{
  for (int i(0); i < 3; ++i) array[i] += a2[i];
}

gutes Beispiel. aber warum ist die Vorlage <Typname T> in der Klasse definitino ... ???
— Martian2049

@ Martian2049 Ich glaube, dies ist so, dass die Vorlage nur für die Elementfunktion innerhalb der Klasse gilt und nicht für die Klasse als Ganzes. Genau wie das OP gefragt hat.
— CBK

21

Ja, Vorlagenelementfunktionen sind bei zahlreichen Gelegenheiten vollkommen legal und nützlich.

Die einzige Einschränkung besteht darin, dass Vorlagenelementfunktionen nicht virtuell sein können.


9

Der einfachste Weg besteht darin, die Deklaration und Definition in derselben Datei abzulegen. Dies kann jedoch zu einer übergroßen auslösbaren Datei führen. Z.B

class Foo
{
public:
template <typename T> void some_method(T t) {//...}
}

Es ist auch möglich, die Vorlagendefinition in die separaten Dateien einzufügen, dh sie in CPP- und H-Dateien abzulegen. Alles, was Sie tun müssen, ist, die Vorlageninstanziierung explizit in die CPP-Dateien aufzunehmen. Z.B

// .h file
class Foo
{
public:
template <typename T> void some_method(T t);
}

// .cpp file
//...
template <typename T> void Foo::some_method(T t) 
{//...}
//...

template void Foo::some_method<int>(int);
template void Foo::some_method<double>(double);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.