27

A class:

template<typename C, typename T>
class A
{
    template <typename U>
    class Nested{};

    Nested<T> n;
};

And I want to specialize Nested. Here what I tried:

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

My next attempt:

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)"

Here on stackoverflow I found a solution:

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

It perfectly works, but I can't understand how. Why to provide a dummy template argument? Why can't I use raw specialization template<> class Nested<int, true>{} or template<> class Nested<int>{}?

0

2 Answers 2

27

It's forbidden to create explicit specialization in class-scope:

An explicit specialization shall be declared in a namespace enclosing the specialized template.

But it's not forbidden to create partial specialization:

A class template partial specialization may be declared or redeclared in any namespace scope in which its definition may be defined (14.5.1 and 14.5.2).

this

template <bool Dummy>
class Nested<int, Dummy>{}; // why need to provide an argument??

is partial specialization and it's allowed to create such specialization in class-scope. You also cannot fully specialize nested class, in not-specialized outer class. You can do this:

template<>
template<>
class A<int, double>::Nested<int>
{
};

but you cannot do

template<typename C, typename T>
template<>
class A<C, T>::Nested<int>
{
};
Sign up to request clarification or add additional context in comments.

Comments

1

I managed to get this to work, by defining all the contents of the specialized template class within the outer class. So all functions are completely defined withing the class definition. No external function definitions, as that did not seem to complile. I.e.

template <typename T, size_t N>
class A
{
private:
    template <size_t M>
    class B
    {
        ...
    };

    template <>
    class B<2>
    {
        ...
    };
    ... etc
};

It worked on MS2015 at least. Code is running just fine.

2 Comments

Yes, but it doesn't run on gcc and clang. Loos like Microsoft not following the standard. Or maybe there's a compiler switch.
@nikitablack cplusplus.github.io/CWG/issues/727.html has been adopted as a defect report

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.