Pregunta

Me parece que C ++ no permite la especialización de la plantilla de miembros en ningún ámbito que no sea el espacio de nombres y el ámbito global (MS VSC ++ Error C3412). Pero para mí tiene sentido especializar la plantilla de miembro principal de una clase base en la clase derivada porque eso es lo que hacen las clases derivadas: especializar las cosas en la clase base. Por ejemplo, considere el siguiente ejemplo:

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.
}

Mi pregunta es ¿por qué no está permitido?

¿Fue útil?

Solución

Entiendo lo que intentas hacer, pero no lo estás haciendo bien. Prueba esto:

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;
};

Otros consejos

  

Mi pregunta es ¿por qué no está permitido?

Desde mi copia del borrador, parece que lo siguiente pone la restricción anterior:

  

En   una declaración de especialización explícita para una plantilla de clase, un miembro de una plantilla de clase o un miembro de clase   plantilla, el nombre de la clase que está explícitamente especializada será simple-template-id.

La solución es especializar la clase adjunta.

Voy a " ignorar " Las especificaciones estándar y probar un argumento lógico:

Si tienes dos clases:

class A
{
   struct S { };

};

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

A :: S y B :: S son dos tipos diferentes. Extendiendo la lógica a las especializaciones de la plantilla, cuando intenta especializar una clase interna declarada en la clase base a través de una clase interna en la clase derivada, en realidad está tratando de definir un tipo diferente, con el mismo nombre (pero con otro ámbito de denominación).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top