Подтвердить что ты не робот

Специализация шаблона вложенного класса

Класс:

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>{}?

4b9b3361

Ответ 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. Код работает нормально.