Alex Rivera | Logout

specialize a member template without specializing its parent

Asked 2010-01-05T23:25:12.843
10

I have a class template nested inside another template. Partially specializing it is easy: I just declare another template< … > block inside its parent.

However, I need another partial specialization that happens to specify all its local template arguments. This makes it into an explicit specialization. Explicit specializations, for whatever reason, must be at namespace scope. To declare it outside its parent class, the parent must be nominated, which requires a non-empty template argument list. This implies partial specialization. Partial specialization is what I'm doing, and it's supposed to work at arbitrary outer scope. But both GCC and Comeau fail to identify the template parameter in the parent nomination with the partial specialization formal arguments.

template< class X > struct A {
    template< class Y > struct B; // initial declaration OK

    template< class Z >
    struct B< A< Z > > {}; // partial OK as long as there's a local arg

    template<> // ERROR: this syntax triggers explicit specialization
    struct B< int > {};
};

template<> // ERROR: can't nest template<>s here (why?)
template< class X > // ERROR: can't deduce X from type of A<X>::B<int> (why?)
struct A< X >::B< int > {};

(I left all my non-working code in; comment it appropriately to attempt to make sense.)

Edit
Report

1 Answer

0

Atleast this works in VC 2010. But, I am unable to write the def. of fun() for "int" outside the class declaration. EDIT: Unfortunately g++ has also compilations issues. EDIT: The code below worked on VC 2010.

template<typename X>
class A
{
public:
    A()
    {

    }

    template<typename Y>
    struct B
    {
        void fun();
    };

    template<>
    struct B<int>
    {
        void fun()
        {
            cout << "Specialized version called\n";
        }
        //void fun();
    };



public:

    B<X> b;
};



template<typename X>
template<typename Y>
void A<X>::B<Y>::fun()
{
    cout << "templated version called\n";
}

int main()
{
   A<int> a;
    a.b.fun();
    A<float> a1;
    a1.b.fun();
}
answered 2010-01-06T01:09:08.567

Your Answer