Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specializing inner template with default parameters

I'm having trouble specializing an inner template when it's parameters are all known. Here's an example:

template < typename T0 >
struct outer
{
    template < typename T1 = void, typename T2 = void >
    struct inner
    {
        typedef T1 type;
    };
};
template < typename T0 >
template < typename T1 >
struct outer<T0>::inner<double,T1> { typedef int type; };

This works just fine. If I instead specify the inner template like so, it does not:

template < typename T0 >
template < >
struct outer<T0>::inner<double,void> { typedef int type; };

For this I get the error message, "invalid explicit specialization before ‘>’ token...enclosing class templates are not explicitly specialized...template parameters not used in partial specialization:...T0". Not sure WTAF is going on here.

I also tried this:

template < typename T0 >
struct outer<T0>::inner<double,void> { typedef int type; };

I expected this to fail and the error message is not surprising. It was: "too few template-parameter-lists".

So, what's the correct way to do this? I can of course hack around it, but if I don't have to I'd prefer not.

like image 293
Edward Strange Avatar asked Jun 16 '13 02:06

Edward Strange


1 Answers

That is not allowed. You cannot fully specialize a member of a class template that has not been itself fully specialized.

Per paragraph 14.7.16 of the C++11 Standard:

In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. [...]

Also, paragraph 14.7.3/15 of the C++11 Standard says:

A member or a member template may be nested within many enclosing class templates. In an explicit specialization for such a member, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized. [ Example:

template<class T1> class A {
     template<class T2> class B {
         void mf();
     };
};
template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();

end example ]

like image 53
Andy Prowl Avatar answered Oct 26 '22 07:10

Andy Prowl