специализация шаблона участника и ее область применения
-
03-07-2019 - |
Вопрос
Мне кажется, что 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 - это два разных типа.Расширяя логику до специализаций шаблона, когда вы пытаетесь специализировать внутренний класс, объявленный в базовом классе, через внутренний класс в производном классе, вы фактически пытаетесь определить другой тип с тем же именем (но другой областью именования).