Reputation: 10685
Suppose I have a template class with a lot of functions and I want to specialize them to change only a few of them and keep the other ones exactly as specified in the base template class.
How can I do that?
Below is what I want to achieve, but the solution isn't good, because it does not allow me to refer to the specialization for int
as Base<int>
– I need to use IntSpec
for that.
#include <iostream>
using namespace std;
template<typename T>
struct Base
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
struct IntSpec : public Base<int>
{
void print2() {cout << "Base<int>::print2()" << endl;};
};
int main()
{
Base<double> d;
// Base<int> i; <-- I want this kind of instantiation
IntSpec i;
d.print1();
d.print2();
i.print1();
i.print2();
}
The output is:
Base::print1
Base::print2
Base::print1
Base<int>::print2()
Upvotes: 36
Views: 23630
Reputation: 21910
Nicol's solution works fine, but this is an alternative:
template<typename T>
struct Base
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
template<>
void Base<int>::print2() {cout << "Base<int>::print2()" << endl;};
That way you can specialize only specific member functions and still use those that you haven't specialized(in this case, print1
) without any problem. So now you'd use it just like you wanted:
Base<int> i;
i.print1();
i.print2(); // calls your specialization
Demo here.
Upvotes: 50
Reputation: 389
Another solution would be to add a level of indirection in the function you want to redefine, i.e.
template<typename T>
struct foo
{
template<typename T2>
void bar_impl()
{
//generic function
}
void bar()
{
bar_impl<T>();
}
};
Then you can specialize each function individually for each type or specialize the whole type as wanted.
Upvotes: 4
Reputation: 474436
You just have to use two template classes:
template<typename T>
struct CommonBase
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
template<typename T>
struct Base : public CommonBase<T>
{
};
template<>
struct Base<int> : public CommonBase<int>
{
void print2() {cout << "Base::print2" << endl;};
};
You always use Base
, rather than CommonBase
.
Upvotes: 33