Специализация шаблона вложенного класса
Класс:
template<typename C, typename T>
class A
{
template <typename U>
class Nested{};
Nested<T> n;
};
И я хочу специализироваться Nested
. Вот что я пробовал:
template<typename C, typename T>
class A
{
template <typename U>
class Nested{};
template <>
class Nested<int>{}; // by my logic this should work by I have a compilation error "explicit specialization in non-namespace scope 'class A<C, T>'"
Nested<T> n;
};
Моя следующая попытка:
template<typename C, typename T>
class A
{
template <typename U>
class Nested{};
Nested<T> n;
};
template<>
A<>::Nested<int>{}; // What is the correct syntax to do it here? Now I have an error "wrong number of template arguments (0, should be 2)"
Здесь, в stackoverflow, я нашел решение:
template<typename C, typename T>
class A
{
template <typename U, bool Dummy = true>
class Nested{}; // why need of this Dummy??
template <bool Dummy>
class Nested<int, Dummy>{}; // why need to provide an argument??
Nested<T> n;
};
Это прекрасно работает, но я не могу понять, как это сделать. Почему необходимо предоставить аргумент шаблона шаблона? Почему я не могу использовать сырую специализацию template<> class Nested<int, true>{}
или template<> class Nested<int>{}
?
Ответы
Ответ 1
Запрещено создавать явную специализацию в классе-области:
Явная специализация объявляется в пространстве имен, охватывающих специализированный шаблон.
Но это не запрещено создавать частичную специализацию:
Частичная специализация шаблона шаблона может быть объявлена или обновлена в любой области пространства имен, в которой может быть определено его определение (14.5.1 и 14.5.2).
это
template <bool Dummy>
class Nested<int, Dummy>{}; // why need to provide an argument??
является частичной специализацией, и это позволяет создавать такую специализацию в классе-сфере. Вы также не можете полностью специализировать вложенный класс в неспецифическом внешнем классе. Вы можете сделать это:
template<>
template<>
class A<int, double>::Nested<int>
{
};
но вы не можете сделать
template<typename C, typename T>
template<>
class A<C, T>::Nested<int>
{
};
Ответ 2
Мне удалось заставить это работать, определив все содержимое специализированного класса шаблонов во внешнем классе. Таким образом, все функции полностью определены с определением класса. Никаких определений внешних функций, поскольку это, похоже, не усложнялось. То есть.
template <typename T, size_t N>
class A
{
private:
template <size_t M>
class B
{
...
};
template <>
class B<2>
{
...
};
... etc
};
Он работал, по крайней мере, на MS2015. Код работает нормально.