специализация шаблона участника и его область применения - PullRequest
4 голосов
/ 30 апреля 2009

Мне кажется, что 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.
}

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

Ответы [ 3 ]

4 голосов
/ 30 апреля 2009

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

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;
};
1 голос
/ 30 апреля 2009

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

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

class A
{
   struct S { };

};

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

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

1 голос
/ 30 апреля 2009

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

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

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

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

...