471,305 Members | 1,468 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,305 software developers and data experts.

Class template specialization

I have a class template. Each of the instantiations implements a method
in the class template differently, so I (need?) to use template
speciaization.

My question is this, when writing the specialization, do I need to
implement only the method that is 'different', or do I need to implement
all the methods in the class template?
template <typename T1, typename T2>
class MyClass
{
void foo(const T1&, T2&) const;
...
//other methods follow below
int foobar(T1, T1, T2&);
// ...etc
};

template<>
class MyClass<int,double>
{
void foo(const int& i, double& d) const
{
//'specialized' logic here
}

/* Do I need all the other methods here ?
.... */
};
Nov 4 '08 #1
7 2381
On Nov 3, 7:22*pm, "(2b|!2b)==?" <void-s...@ursa-major.comwrote:
I have a class template. Each of the instantiations implements a method
in the class template differently, so I (need?) to use template
speciaization.

My question is this, when writing the specialization, do I need to
implement only the method that is 'different', or do I need to implement
all the methods in the class template?

template <typename T1, typename T2>
class MyClass
{
public:
* *void foo(const T1&, T2&) const;
* *...
* *//other methods follow below
* *int foobar(T1, T1, T2&);
* *// ...etc

};

template<>
class MyClass<int,double>
{
public:
* * *void foo(const int& i, double& d) const
* * *{
* * * * //'specialized' logic here
* * *}

* * /* Do I need all the other methods here ?
* * *.... */

};
Yes, You'll need to provide specialization for the entire type.
To partially specialize a template, derive from the generic one:

class DerivedClass : public MyClass< int, double >
{
public:
void foo(const int& i, double& d) const
{
// do specialized stuff here
}
};

foo(...) now overides any foo(...) in the base class and foobar() is
available.
This works too:

template< typename N = int, typename D = double >
class DerivedClass : public MyClass< N, D >
{
public:
void foo(const N& i, D& d) const
{
std::cout << "DerivedClass::foo(const int&, double&) const\n";
}
};

DerivedClass< instance;
instance.foobar(...);

Nov 4 '08 #2
On 4 Nov, 01:22, "(2b|!2b)==?" <void-s...@ursa-major.comwrote:
I have a class template. Each of the instantiations implements a method
in the class template differently, so I (need?) to use template
speciaization.

My question is this, when writing the specialization, do I need to
implement only the method that is 'different', or do I need to implement
all the methods in the class template?

template <typename T1, typename T2>
class MyClass
{
* *void foo(const T1&, T2&) const;
* *...
* *//other methods follow below
* *int foobar(T1, T1, T2&);
* *// ...etc

};
If only the function body is different, you could simply do this:

template<>
void MyClass<int, double>::foo(const int&, double&) const
{
// ...
}
template<>
void MyClass<double, double>::foo(const double&, double&) const
{
// ...
}
Nov 4 '08 #3
Triple-DES wrote:
On 4 Nov, 01:22, "(2b|!2b)==?" <void-s...@ursa-major.comwrote:
>I have a class template. Each of the instantiations implements a method
in the class template differently, so I (need?) to use template
speciaization.

My question is this, when writing the specialization, do I need to
implement only the method that is 'different', or do I need to implement
all the methods in the class template?

template <typename T1, typename T2>
class MyClass
{
void foo(const T1&, T2&) const;
...
//other methods follow below
int foobar(T1, T1, T2&);
// ...etc

};

If only the function body is different, you could simply do this:

template<>
void MyClass<int, double>::foo(const int&, double&) const
{
// ...
}
template<>
void MyClass<double, double>::foo(const double&, double&) const
{
// ...
}
That would be explicit instantiation, or what's that called
officially?

Schobi
Nov 7 '08 #4
Hendrik Schober wrote:
>>template <typename T1, typename T2>
class MyClass
{
void foo(const T1&, T2&) const;
...
//other methods follow below
int foobar(T1, T1, T2&);
// ...etc

};

If only the function body is different, you could simply do this:

template<>
void MyClass<int, double>::foo(const int&, double&) const
{
// ...
}
template<>
void MyClass<double, double>::foo(const double&, double&) const
{
// ...
}

That would be explicit instantiation, or what's that called
officially?
That's called "explicit specialization" (the 'template<>' bit is usually
a dead giveaway). When it comes to explicit specialization, the class
itself and the members of the class are pretty much independent
templates. You can perform explicit specialization on them
independently. You can explicitly specialize the entire class template
(meaning that you'll have to redefine the whole thing from scratch), or
you can explicitly specialize the members (without specializing the
entire class). The latter is what's done in the above code.

Of course, once you decided to explicitly specialize the entire class
template for type 'T', you can no longer explicitly specialize just the
members for the same type 'T'.

--
Best regards,
Andrey Tarasevich
Nov 8 '08 #5
Andrey Tarasevich wrote:
Hendrik Schober wrote:
>>>template <typename T1, typename T2>
class MyClass
{
void foo(const T1&, T2&) const;
...
//other methods follow below
int foobar(T1, T1, T2&);
// ...etc

};
If only the function body is different, you could simply do this:

template<>
void MyClass<int, double>::foo(const int&, double&) const
{
// ...
}
template<>
void MyClass<double, double>::foo(const double&, double&) const
{
// ...
}
That would be explicit instantiation, or what's that called
officially?

That's called "explicit specialization" (the 'template<>' bit is usually
a dead giveaway). When it comes to explicit specialization, the class
itself and the members of the class are pretty much independent
templates. You can perform explicit specialization on them
independently. You can explicitly specialize the entire class template
(meaning that you'll have to redefine the whole thing from scratch), or
you can explicitly specialize the members (without specializing the
entire class). The latter is what's done in the above code.

Of course, once you decided to explicitly specialize the entire class
template for type 'T', you can no longer explicitly specialize just the
members for the same type 'T'.
Oh, I thought explicit specialization of class template members
wasn't allowed? Oh wait, that was explicit specialization of
member templates, right? <sigh>

Schobi
Nov 9 '08 #6
Hendrik Schober wrote:
>
Oh, I thought explicit specialization of class template members
wasn't allowed? Oh wait, that was explicit specialization of
member templates, right? <sigh>
Right. It is a completely different issue.

BTW, even that is allowed, as long as you explicitly specialize the
enclosing template as well

template <class Tstruct C {
template <class Ustruct D {};
};

template<template<struct C<int>::D<double{}; // OK

--
Best regards,
Andrey Tarasevich

Nov 9 '08 #7
Andrey Tarasevich wrote:
Hendrik Schober wrote:
> Oh, I thought explicit specialization of class template members
wasn't allowed? Oh wait, that was explicit specialization of
member templates, right? <sigh>

Right. It is a completely different issue.

BTW, even that is allowed, as long as you explicitly specialize the
enclosing template as well

template <class Tstruct C {
template <class Ustruct D {};
};

template<template<struct C<int>::D<double{}; // OK
Thanks.
So the only thing disallowed would be explicit specialization
of member templates of unspecialized class templates?

Schobi
Nov 9 '08 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by jesse | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.