Reputation: 1999
It is possible to use template specialization to achieve stuff like this:
template <typename T>
T bar(T baz);
template <>
static unsigned int bar<unsigned int>(unsigned int baz)
{
return baz + 1;
}
template <>
static int bar<int>(int baz)
{
return baz + 2;
}
But what if the template parameters are on a class that contains the method?
template <typename T>
class Foo
{
T fooBar(T baz);
};
How can I (if at all) use template specialization to implement different forms of the fooBar method like I did above?
Thanks
Upvotes: 2
Views: 99
Reputation: 168958
The same basic way, you just have to make it clear where the template is.
This would be wrong, because while the method is implicitly a template (because the class is) it "inherits" the template types from the class:
template <>
inline unsigned int Foo::fooBar<unsigned int>(unsigned int baz)
So instead, specify the type after the class:
template <>
inline unsigned int Foo<unsigned int>::fooBar(unsigned int baz)
{
return baz + 1;
}
template <>
inline int Foo<int>::fooBar(int baz)
{
return baz + 2;
}
(Demo)
Note that inline
is required here since these are not template functions, but rather are specializations. Therefore, they must follow the One Definition Rule. inline
suppresses the ODR as with any other non-template function/method definition.
Alternatively, you could declare them in the header and implement them in an implementation file:
// Header file
template <>
unsigned int Foo<unsigned int>::fooBar(unsigned int baz);
template <>
int Foo<int>::fooBar(int baz);
// Implementation file
template <>
unsigned int Foo<unsigned int>::fooBar(unsigned int baz)
{
return baz + 1;
}
template <>
int Foo<int>::fooBar(int baz)
{
return baz + 2;
}
The same basic syntax applies to template methods in template types, except you need two template <>
since you are specializing two different levels of templates:
template <typename T>
class Foo
{
public:
template <typename U>
void foobar(T t, U u);
};
// Specialization of T=int, U=unsigned int
template <>
template <>
inline void Foo<int>::foobar<unsigned int>(int t, unsigned int u)
{
// ...
}
Upvotes: 7