Frage

Ist das folgende Design möglich ?:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

Wenn es möglich wäre, würde ich einige explizite Spezialisierungen für Dosen machen, so dass ich am Ende einige Versionen wie unten habe:

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

Was unmöglich erscheint, kann ich keine Syntax finden, um den Job zu erledigen, dann dachte ich, das Design sollte sein, wie es folgt, damit alle Vorlagenargumente an die Vorlagenklasse selbst übergeben werden sollten:

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

Dann habe ich eine teilweise Spezialisierung ausprobiert, die nicht einmal kompilierte:

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

Ich habe die folgenden Fehler für die explizite Spezialisierung erhalten:
Fehler Nr. 1: Vorlagenargumentliste Der folgende Klassenvorlagenname muss Parameter in der in der Vorlagenparameterliste verwendeten Reihenfolge auflisten.
Fehler Nr. 2: 'Container1': Zu wenige Vorlagenargumente.

War es hilfreich?

Lösung

Um explizit spezialisiert zu werden doSomething Sie müssen sich auch ausdrücklich spezialisieren Test.

Von 14.7.3/18:

In einer expliziten Spezialisierungserklärung für ein Mitglied einer Klassenvorlage oder eine Mitgliedsvorlage, die im Namespace -Bereich erscheint, können die Mitgliedsvorlage und einige seiner umschließenden Klassenvorlagen unspezialisiert bleiben. außer dass die Erklärung eine Klassenmitgliedsvorlage nicht ausdrücklich spezialisiert ist, wenn ihre umschließenden Klassenvorlagen auch nicht explizit spezialisiert sind.

Andere Tipps

Sie können eine Mitgliedsvorlage nicht explizit spezialisiert, es sei denn, seine umschließenden Klassenvorlagen sind ebenfalls explizit spezialisiert.

So wird also nur so etwas funktionieren:

template<> template<>
void Test<int>::doSomething<int>()
{
}

Sie können die Funktion immer inline machen

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};

Ich denke, das ist wählerisch. Ich nehme an, Sie können es nicht tun, lesen Dies.

Ich bin mir nicht sicher, ob dies ein Fehler in G ++ ist, aber dies kompiliert und produziert das, was ich erwarte.

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}

Icecrime hat eine temporäre Antwort gepostet und sie wird aufgrund eines Fehlers, wahrscheinlich von Visual C ++ 2008, zusammengestellt:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

Überprüfen Sie jedoch seine aktuelle Antwort. Das Lustige zumindest mit VC ++ 2008 ist, kein Problem mit der Kompilierung bei der Spezialisierung auf Inline-Definitionen, aber für Spezialisierungen mit nicht-inline-Definitionen, sobald es mehr als eine Version gibt, wird es nicht erfolgreich zusammengestellt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top