Question

Il me semble que C ++ n'autorise pas la spécialisation de modèle de membre dans une étendue autre que l'espace de noms et l'étendue globale (erreur MS VSC ++ C3412). Mais pour moi, il est logique de spécialiser le modèle de membre principal d'une classe de base dans la classe dérivée, car c'est ce que font les classes dérivées - spécialiser les éléments de la classe de base. Par exemple, considérons l'exemple suivant:

struct Base
{
  template <class T>
  struct Kind
  {
      typedef T type;
  };
};

struct Derived : public Base
{
  /* Not Allowed */
  using Base::Kind;
  template <>
  struct Kind <float> 
  {
    typedef double type;
  };
};

int main(void)
{
  Base::Kind<float>::type f;    // float type desired
  Derived::Kind<float>::type i; // double type desired but does not work.
}

Ma question est: pourquoi est-ce interdit?

Était-ce utile?

La solution

Je comprends ce que vous essayez de faire, mais vous ne le faites pas correctement. Essayez ceci:

struct Base{};
struct Derived{};

// Original definition of Kind
// Will yield an error if Kind is not used properly
template<typename WhatToDo, typename T>
struct Kind
{
};

// definition of Kind for Base selector
template<typename T>
struct Kind<Base, T>
{
  typedef T type;
};

// Here is the inheritance you wanted
template<typename T>
struct Kind<Derived, T> : Kind<Base, T>
{
};

// ... and the specialization for float
template<>
struct Kind<Derived, float>
{
  typedef double type;
};

Autres conseils

  

Ma question est: pourquoi est-ce interdit?

D'après ma copie du projet, il apparaît que ce qui suit place la restriction ci-dessus:

  

Dans   une déclaration de spécialisation explicite pour un modèle de classe, un membre d'un modèle de classe ou un membre de classe   template, le nom de la classe explicitement spécialisée doit être un simple-template-id.

La solution consiste à spécialiser la classe englobante.

Je vais "ignorer" les spécifications standard et essayez un argument logique:

Si vous avez deux classes:

class A
{
   struct S { };

};

class B: public A
{
   struct S { };
};

A :: S et B :: S sont deux types différents. En étendant la logique aux spécialisations de modèle, lorsque vous essayez de spécialiser une classe interne déclarée dans la classe de base par le biais d'une classe interne dans une classe dérivée, vous essayez en fait de définir un type différent, avec le même nom (mais une autre portée de dénomination).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top