2

I have problem with my project, here is some test code, in project it looks same. Some of classes are plain but one of them is template class with 2 different types (class B) for example int and double.

class Bar
{
    Bar()
    {
    }
};

template< typename _T >
class B
{
    B();
};

template< typename _T >
B<_T>::B()
{
}

typedef B<int> Bint;
typedef B<double> Bdouble;

template< typename _T >
class Test
{
    Test();
    void method();
};

template< typename _T >
Test<_T>::Test()
{
}

template< typename _T >
void
Test<_T>::method()
{
}

template< >
void
Test< Bar >::method()
{
   //do sth for Bar
}

I know i can do it by spcializing B<int> and B<double> for template argument but it doubles the code. Here is te problem, i want to specialize method for only template B class, is ther any way to do it ? I know this code won't work :

template< >
void
Test< B< _T> >::method()
{
   ////do sth for B< _T >
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
n0n1ck
  • 23
  • 2
  • 4
    Replace `_T` with `T` as the former is reserved and you are not allowed to use it in your code. – Daniel Frey Sep 17 '13 at 07:55
  • 1
    see [this question about rules for using underscores](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier/228797#228797) – Hulk Sep 17 '13 at 08:17

1 Answers1

3

The solution is a bit complicated, see the inline comments for some explanation

class Bar
{
    Bar() {}
};

template< typename T >
class B
{
    B() {}
};

typedef B<int> Bint;
typedef B<double> Bdouble;

template< typename T >
class Test
{
    Test() {}

private:
    // you need one level of indirection
    template<typename U> struct method_impl
    {
        static void apply();
    };
    // declare a partial specialization
    template<typename X> struct method_impl< B<X> >
    {
        static void apply();
    };

public:
    // forward call to the above
    void method() { method_impl<T>::apply(); }
};

// and now you can implement the methods
template< typename T >
template< typename U >
void
Test<T>::method_impl<U>::apply()
{
    // generic implementation
}

template<>
template<>
void
Test< Bar >::method_impl<Bar>::apply()
{
    //do sth for Bar
}

template< typename T >
template< typename X >
void
Test< T >::method_impl< B<X> >::apply()
{
    //do sth for B<X>
}
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • There is still problem: error C2995: 'void Test::method(void)' : function template has already been defined due to template< typename T > void Test::method() { } – n0n1ck Sep 17 '13 at 09:22
  • @n0n1ck Sorry, I missed an important thing. I fixed the answer although it's now a bit more complicated. I tested it with GCC 4.8 and I hope VC++ can handle it as well. Check if it works for you... – Daniel Frey Sep 17 '13 at 09:53