Reputation: 2055
Considering a template function like below how is it possible to do explicitly specialize one version of function for multiple types:
template <typename T>
void doSomething(){
//whatever
}
The intention is to have one specialization instead of multiple following ones because //something is the same:
void doSomething<int>(){
//something
}
void doSomething<float>(){
//something
}
void doSomething<double>(){
//something
}
any method to achieve one specialization?
Upvotes: 4
Views: 2422
Reputation: 11
using c++ 2011 (option -std=c++11), this works well:
#include <iostream>
template <typename T>
struct unsignedObject
{
unsignedObject() {
std::cout << "instanciate a unsignedObject\n";
}
};
struct signedObject
{
signedObject() {
std::cout << "instanciate a signedObject\n";
}
};
template <typename T>
struct objectImpl
{
typedef unsignedObject<T> impl; // optional default implementation (the line can be removed)
};
template <> struct objectImpl<unsigned char> { typedef unsignedObject<unsigned char> impl; };
template <> struct objectImpl<unsigned int> { typedef unsignedObject<unsigned int> impl; };
template <> struct objectImpl<unsigned short> { typedef unsignedObject<unsigned short> impl; };
template <> struct objectImpl<double> { typedef signedObject impl; };
template <> struct objectImpl<int> { typedef signedObject impl; };
template <> struct objectImpl<short> { typedef signedObject impl; };
template <> struct objectImpl<char> { typedef signedObject impl; };
template <typename T>
using object = typename objectImpl<T>::impl;
int main(void)
{
object<int> x; // x is a signedObject.
object<double> y; // y is a signedObject.
object<unsigned short> z; // z is a unsignedObject.
return 0;
}
Upvotes: 1
Reputation: 14341
You can't make template function specialization. But you could delegate the implementation in a helper class, that can be used from your function. Some skeleton code:
Implement a template class and specialize it:
template< typename T, bool isArithmetic>
struct Something { void operator()() { ... } };
template< typename T, true>
struct Something { void operator()() { ... do something specialized for arithmetic types; } }
Then use it in the template function:
template< typename T>
void myFunction()
{
Something<T, IsArithmetic<T>::value>()();
}
Where IsArithmetic is a class that provides the information about type T (selector). You can find such type info in boost libraries, for example.
Upvotes: 4
Reputation: 146910
You could just have a kind of doSomethingImpl function.
template<typename T> doSomethingImpl() {
// whatever
}
template<typename T> doSomething() {
// something else
}
template<> doSomething<float>() {
doSomethingImpl<float>();
}
template<> doSomething<int>() {
doSomethingImpl<int>();
}
It's also possible to specialize more generically, using SFINAE and std::is_numeric<T>
, for example.
Upvotes: 1