Partial pattern specification outside the class definition

I can use partial specialization of templates inside a class declaration

template<class T1, class T2> struct A { void foo() { cout << "general"; } }; template<class T1> struct A<T1, int> { void foo() { cout << "partial specialization"; } }; 

But when I try to do this outside the class declaration

 template<class T1, class T2> struct A { void foo(); }; template<class T1, class T2> void A<T1, T2>::foo() { cout << "general"; } template<class T1> void A<T1, int>::foo() { cout << "partial specialization"; } 

I get the following error:

invalid use of incomplete type "struct A <T1, int>"

You should not use the first approach when you want to redefine all members, but what if you want to redefine only one method without code duplication for all others?

So, is it possible to use the partial template specification outside the class definition?

+3
source share
4 answers

You should not use the first approach when you want to redefine all members, but what if you want to redefine only one method without code duplication for all others?

Here you can use the feature technique. See http://www.boost.org/community/generic_programming.html#traits

Some uses:

 template <class T1, class T2> struct ATraits { static void foo() {} }; template <class T1> struct ATraits<T1,int> { static void foo() {} }; template <class T1, class T2> struct A { void foo() { ATraits<T1,T2>::foo(); } }; 
+2
source

Specialization of the method without full specialization of the external template is prohibited by the C ++ standard. So this is not possible. I'm not sure if this is true for C ++ 11, but I suspect it is.

One way around this is to specialize the external template, as you did in the first example.

Btw this could be another way:

 template<class T1, class T2> struct A { template<unsigned int I> void foo() { cout << "general"; } template<> void foo<2> () { cout << "specialization"; } }; 

This works because it is not a specialization, but a different template for this method.

+2
source

In your unsuccessful example:

 template<class T1> void A<T1, int>::foo() { cout << "partial specialization"; } 

You mean the specialization A that you have not yet defined (in the second example, you only defined the complete template).

If you add a specialization before referencing it, it really should work:

 template <class T1> struct A<T1, int> { void foo (); }; template <class T1> void A<T1, int>::foo () { /* something */ }; 
+2
source

The same topics are discussed here: "Invalid use of incomplete type" error with partial template specialization

+1 for tozka's solution, if A doesn't need to know I, except foo (), this is a good workaround. Otherwise, take a look at the answers to the above question.

0
source

All Articles