96 votes

explicite de la spécialisation du modèle de fonction membre de classe

J'ai besoin de spécialiser modèle de fonction de membre d'un certain type (disons double). Il fonctionne très bien, tandis que la classe X lui-même n'est pas un modèle de classe, mais lorsque je fais de modèle GCC commence à donner des erreurs de compilation.

#include <iostream>
#include <cmath>

template <class C> class X
{
public:
   template <class T> void get_as();
};

template <class C>
void X<C>::get_as<double>()
{

}

int main()
{
   X<int> x;
   x.get_as();
}

voici le message d'erreur

source.cpp:11:27: error: template-id
  'get_as<double>' in declaration of primary template
source.cpp:11:6: error: prototype for
  'void X<C>::get_as()' does not match any in class 'X<C>'
source.cpp:7:35: error: candidate is:
  template<class C> template<class T> void X::get_as()

Comment puis-je régler ce problème et quel est le problème ici?

Merci à l'avance.

117voto

Johannes Schaub - litb Points 256113

Il ne fonctionne pas de cette façon. Vous auriez besoin de dire ce qui suit, mais c'est pas correct

template <class C> template<>
void X<C>::get_as<double>()
{

}

Explicitement spécialisé membres ont besoin de leurs entourant les modèles de classe à être explicitement spécialisées ainsi. Vous devez donc vous dire la chose suivante, qui ne serait que de spécialiser les membres de X<int>.

template <> template<>
void X<int>::get_as<double>()
{

}

Si vous souhaitez conserver les environs modèle non spécialisé, vous avez plusieurs choix. Je préfère les surcharges

template <class C> class X
{
   template<typename T> struct type { };

public:
   template <class T> void get_as() {
     get_as(type<T>());
   }

private:
   template<typename T> void get_as(type<T>) {

   }

   void get_as(type<double>) {

   }
};

0voto

Serge Dundich Points 1682

Tout d'abord: vous n'avez pas get_as spécialisation déclaré dans votre modèle de classe pour être défini plus tard dans un code. Alors d'abord vous avez besoin pour ce faire:

template <class C> class X
{
public:
   template <class T> void get_as();
   template <> void get_as<double>();
};

Ensuite, de définir la spécialisation:

template <class C>
template <>
void X<C>::get_as<double>()
{
....
}

Mais je tiens à le définir comme ceci:

template <class C> class X
{
public:
   template <class T> void get_as()
   {
   // default implementation
   }

   template <> void get_as<double>()
   {
   // specialized implementation
   }
};

DÉSOLÉ, LE CI-DESSUS NE FONCTIONNE PAS!

EDIT:

Il s'avère que le modèle de fonction de spécialisations ne sont pas autorisés dans le non-espace de noms de la portée, c'est à dire dans les classes, les modèles de classe, etc.

De sorte que vous pouvez faire est aussi de l'espace de noms de la portée de la fonction de modèle:

template <class C> class X
{
public:
}

template <class T, class C> void get_as( X<C>& obj )
{
// default implementation
}

template <class C> void get_as<double,C>( X<C>& obj )
{
// specialized implementation
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X