I\'m currently refactoring some code the explicitly specializes a member function of a class template with two template parameters.
template
You can achieve that by using a specialize functor instead a function :
#include <iostream>
typedef int SomeType;
template <class A, class B>
class BarFunctor {
public:
void operator()() {
std::cout << "generic" << std::endl;
}
};
template <>
class BarFunctor<SomeType, SomeType> {
public:
void operator()() {
std::cout << "special" << std::endl;
}
};
template <class S, class T, class EXTRA0, class EXTRA1>
class Foo {
public:
void helloWorld() {
std::cout << "hello world !" << std::endl;
}
void bar() {
return _bar();
}
private:
BarFunctor<S, T> _bar;
};
int main() {
Foo<char, char, char, char> gen;
Foo<SomeType, SomeType, char, char> spe;
gen.helloWorld();
spe.helloWorld();
gen.bar();
spe.bar();
return 0;
}
You can make Base class , where you can define all your members except bar() and then create derivative classes(one for general purpose, one for SomeType):
template <class S, class T>
class FooBase
{
// All other members
};
template <class S, class EXTRA0, class T, class EXTRA1>
class Foo:public FooBase<S,T>
{
public:
void bar()
{
}
};
struct SomeType {};
template <class EXTRA0, class EXTRA1>
class Foo<SomeType,EXTRA0,SomeType,EXTRA1>:public FooBase<SomeType,SomeType>
{
public:
void bar()
{
}
};
int main()
{
Foo<SomeType,int,SomeType,int> b;
b.bar();
}
You are correct, it is not possible.
What you can do is create a helper member class template inside the new Foo
, and place the specialized function inside it as a non-template member function. Specialize the helper class instead of the function.
Another alternative is to turn the specialization into a non-template overload.
I do not think that what you want is that easily possible. What about something like this:
template <class S, class EXTRA0, class T, class EXTRA1>
class FooBase
{
void bar();
};
template <class S, class EXTRA0, class T, class EXTRA1>
void FooBase<S, EXTRA0, T, EXTRA1>::bar()
{ /* Generic stuff */ }
template <class S, class EXTRA0, class T, class EXTRA1>
class Foo
: public FooBase <S, EXTRA0, T, EXTRA1>
{ };
template <class EXTRA0, class EXTRA1>
class Foo<int, EXTRA0, int, EXTRA1>
: public FooBase <int, EXTRA0, int, EXTRA1>
{
void bar ();
};
template <class EXTRA0, class EXTRA1>
void Foo<int, EXTRA0, int, EXTRA1>::bar()
{ /* Some special function */ }