Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: partial specialization of template template classes

The following code:

using namespace std;

template <typename X>
class Goo {};


template <typename X>
class Hoo {};


template <class A, template <typename> class B = Goo >
struct Foo {
  B<A> data;
  void foo1();
  void foo2();

};


template <typename A>
void Foo<A>::foo1() { cout << "foo1 for Goo" << endl;}


int main() {
  Foo<int> a;
  a.foo1();

}

gives me a compiler error:

test.cc:18: error: invalid use of incomplete type 'struct Foo<A, Goo>'
test.cc:11: error: declaration of 'struct Foo<A, Goo>'

Why can't I partially specialize foo1() ? If this is not the way, how do I do this?

I have another question: what if I want foo2() to be defined only for A=int, B=Hoo and not for any other combination, how do I do that?

like image 420
user231536 Avatar asked Jan 03 '12 21:01

user231536


People also ask

What is a template partial?

Template partials are small bits of reusable template or tag parts. You could create a Template partial for any number of purposes, anywhere that you need to reuse a small portion of a template, including partial or complete tags, other variables, etc.

Can you partially specialize a C++ function template?

You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.

What is the difference between class template and function template?

For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.

What is meant by template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.


2 Answers

Function templates may only be fully specialized, not partially.

Member functions of class templates are automatically function templates, and they may indeed be specialized, but only fully:

template <>
void Foo<int, Goo>::foo1() { }  // OK

You can partially specialise the entire class and then define it anew:

template <typename A>
struct Foo<A, Goo>
{
  // ...
};

(See 14.7.3 for details.)

like image 147
Kerrek SB Avatar answered Oct 28 '22 13:10

Kerrek SB


The template still has two parameters, and you must write something like this:

template <typename A, template <typename> class B>
void Foo<A,B>::foo1() { cout << "foo1" << endl;}

The default has been specified, and only needs to be specified once. From then on, it's just like any other two-parameter template. This code will apply no matter what B is (defaulted or otherwise). If you then wish to specify different behaviour for a particular B, then you do specialization of the class, not just of a method.

(Heavily edited)

like image 44
Aaron McDaid Avatar answered Oct 28 '22 14:10

Aaron McDaid