11
votes

Appelez la version non spécifiée d'une fonction lors de la spécialisation en C ++?

dire que j'ai une classe modélisée: xxx pré>

et je souhaite spécialiser do_something, mais je veux appeler la fonction "normale" DO_QUSIGHEATHIQUE: P>

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  // and ALSO do something generic!
}


5 commentaires

Il n'y a pas de version «normale» de do_something pour le type MyOBJ - L'effet complet de la spécialisation du modèle est de remplacer l'instanciation que vous auriez Vous avez reçu du modèle de base, avec la classe / la fonction que vous définissez dans la spécialisation.


Dupliquer possible de Comment puis-je obtenir un modèle spécialisé pour utiliser la version non spécifiée d'une fonction membre?


Juste, mais le compilateur connaît le code dans FOO :: do_something, il n'y a aucune raison pour que cela ne puisse pas me laisser se référer en quelque sorte. Je suis totalement disposé à croire que cette fonctionnalité de langue n'existe tout simplement pas, c'est ce que j'essaie de savoir.


@Steve Townsend - C'est une question différente. Cela demande comment vous pouvez avoir une classe avec certaines fonctions spécialisées et certaines fonctions non spécifiées.


"Il n'y a aucune raison pour que cela ne puisse pas me laisser se référer en quelque sorte" - si des modèles ont été définis de manière radicalement différente, il n'y aurait aucune raison. Comme c'est le cas, foo est une classe, et il possède une fonction do_something et cette fonction est définie par la spécialisation. Si le modèle de base foo a été instancié avec paramètre MyOBJ , le résultat serait une autre classe , également foo , qui n'est pas autorisé, et c'est l'obstacle. Je suppose que si la langue vous permet d'instancier le modèle de base à un nom différent, vous serez peut-être bien, mais pas de bonne chance.


3 Réponses :


7
votes

Non. Votre spécialisation est la seule définition qui existera pour l'argument de type MyOBJ. Mais, envisagez de modifier le modèle FOO de cette manière, qui sera transparent pour les utilisateurs actuels du modèle:

template<>
void foo<MyObj>::prelude(MyObj &obj){
  // do something specific
}


1 commentaires

Cela ressemble à une analogie mondiale de modèle pour NVI de Sutter!



1
votes

Vous pouvez également envisager un type qui n'est pas Myobj, mais le convertit implicitement, mais le meilleur moyen serait de refroidir et d'extraire peut-être le générique commun quelque chose.

#include <iostream>
#include <boost/ref.hpp>
typedef int MyObj;


template <typename T>
struct foo {
  void do_something(T obj) {
    // do something generic...
    std::cout << "generic " << obj << '\n';
  }
};

template<>
void foo<MyObj>::do_something(MyObj obj) {
  // do something specific...
  std::cout << "special " << obj << '\n';
  // and ALSO do something generic!
  foo<boost::reference_wrapper<MyObj> >().do_something(boost::ref(obj));
}

int main()
{
    foo<int> f;
    f.do_something(10);
}


0 commentaires

0
votes

Oui, ceci est en fait assez simple. Vous laissez simplement la version principale et générique de votre fonction servir de passage à une fonction générique de «mise en œuvre» qui ne doit pas em> spécialisée partiellement, vous pouvez simplement appeler cela de la version spécialisée de la fonction initiale selon les besoins.

template<>
void foo<MyObj>::do_something(MyObj obj) 
{
  // do something specific...
  do_something_impl(obj); //The generic part
}


0 commentaires