специализация шаблона участника и ее область применения

StackOverflow https://stackoverflow.com/questions/808403

Вопрос

Мне кажется, что C ++ не допускает специализации шаблона-члена в какой-либо области, отличной от пространства имен и глобальной области (ошибка MS VSC ++ C3412).Но для меня имеет смысл специализировать шаблон основного члена базового класса в производном классе, потому что это то, что делают производные классы - специализируют вещи в базовом классе.Например, рассмотрим следующий пример:

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

Мой вопрос в том, почему это запрещено?

Это было полезно?

Решение

Я понимаю, что ты пытаешься сделать, но ты делаешь это неправильно.Попробуй это :

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

Другие советы

Мой вопрос в том, почему это запрещено?

Из моей копии черновика следует, что следующее накладывает вышеуказанное ограничение:

В явном объявлении специализации для шаблона класса, члена шаблона класса или члена класса template именем класса, который явно специализирован, должен быть простой идентификатор шаблона.

Обходной путь заключается в специализации заключающего класса.

Я "проигнорирую" стандартные спецификации и попробую привести логический аргумент:

Если у вас есть два класса:

class A
{
   struct S { };

};

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

A:: S и B :: S - это два разных типа.Расширяя логику до специализаций шаблона, когда вы пытаетесь специализировать внутренний класс, объявленный в базовом классе, через внутренний класс в производном классе, вы фактически пытаетесь определить другой тип с тем же именем (но другой областью именования).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top