Domanda

Mi sembra che C ++ non consenta la specializzazione dei modelli di membri in ambiti diversi dallo spazio dei nomi e dall'ambito globale (errore MS VSC ++ C3412). Ma per me ha senso specializzare il modello di membro principale di una classe base nella classe derivata perché è quello che fanno le classi derivate: specializzare le cose nella classe base. Ad esempio, considera il seguente esempio:

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

La mia domanda è: perché non è permesso?

È stato utile?

Soluzione

Ho quello che stai cercando di fare, ma non lo stai facendo bene. Prova questo:

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

Altri suggerimenti

  

La mia domanda è: perché non è permesso?

Dalla mia copia della bozza sembra che quanto segue pone la restrizione di cui sopra:

  

In   una dichiarazione di specializzazione esplicita per un modello di classe, un membro di un modello di classe o un membro di classe   template, il nome della classe che è esplicitamente specializzata deve essere un id-template-semplice.

La soluzione alternativa è quella di specializzare la classe allegata.

Ignorerò " ignorerò " le specifiche standard e prova un argomento logico:

Se hai due classi:

class A
{
   struct S { };

};

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

A :: S e B :: S sono due tipi diversi. Estendendo la logica alle specializzazioni del modello, quando si tenta di specializzare una classe interna dichiarata nella classe base attraverso una classe interna nella classe derivata, si sta effettivamente cercando di definire un tipo diverso, con lo stesso nome (ma un altro ambito di denominazione).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top