3

I am trying to create a partly specialized member of a templated class, where the inner class's template type is the one coming from the outer class... the following:

template<typename T>
struct Num
{
    template <T n>
    struct VH
    {
        enum { value = n };
        T v = value;
    };
};

template <typename T> struct Num<T>::VH<0>
{
    enum {value = 1};
    T v = value;
};

template <typename T> struct Num<T>::VH<1>
{
    enum {value = 0};
    T v = value;
};

fails with

error: too few template-parameter-lists
     template <typename T> struct Num<T>::VH<0>

and the following:

template <typename T> struct Num<T>::template<> VH<0>
{
    enum {value = 0};
    T v = value;
};

template <typename T> struct Num<T>::template<> VH<1>
{
    enum {value = 1};
    T v = value;
};

just does not feel right (error: expected template-id before '<' token template <typename T> struct Num<T>::template<> VH<0>)

and after reading explicit specialization of template class member function the following

template <typename T> template<> struct Num<T>::VH<0>
{
    enum {value = 0};
    T v = value;
};

template <typename T> template <> struct Num<T>::VH<1>
{
    enum {value = 1};
    T v = value;
};

gives the error:

error: invalid explicit specialization before '>' token
 template <typename T> template<> struct Num<T>::VH<0>
                                ^
error: enclosing class templates are not explicitly specialized
error: template parameters not used in partial specialization:
 template <typename T> template<> struct Num<T>::VH<0>
                                                 ^
error:         'T'

Can anyone let me know the correct syntax for this, I don't seem to be able to figure it out now ...?

Community
  • 1
  • 1
Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167

1 Answers1

5

The syntax would be

template <typename T>
template <>
struct Num<T>::VH<0>
{
    enum {value = 1};
    T v = value;
};

But unfortunately, it is not possible to fully specialize a inner struct. But you can partially specialize it:

With

template<typename T>
struct Num
{
    template <T n, int dummy = 0> // Add extra dummy for partial specialization
    struct VH
    {
        enum { value = n };
        T v = value;
    };
};

Do

template <typename T>
template <int dummy>
struct Num<T>::VH<0, dummy>
{
    enum {value = 1};
    T v = value;
};

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Indded, great answer! http://stackoverflow.com/questions/2537716/why-is-partial-specialziation-of-a-nested-class-template-allowed-while-complete has a detailed explanation. Thanks a lot! – Ferenc Deak Nov 17 '15 at 13:45