Reputation: 16845
Many questions have been asked and they are similar to the one I am going to ask here, but they are not the same I think.
I have a templated class:
namespace app {
template <typename T>
class MyCLass {
public:
void dosome();
void doother();
}
} /*ns*/
And implementations:
template <typename T>
app::MyClass<T>::dosome() {}
template <typename T>
app::MyClass<T>::doother() {}
When I have an instance of that class to which a char
is provided as template parameter, I want function dosome()
to behave in a totally different way.
But I just want that function to behave differently, everything else must still act the same.
I tried typing:
template<>
app::MyCLass<char>::dosome() {
}
But the compiler tells me that I am trying to create a specialization in a different namespace.
So when I have a code like this:
app::MyCLass<int> a;
app::MyCLass<char> b;
a.dosome(); // This must call the generic template definition
b.dosome(); // This must call the specialization
a.doother(); // This must call the generic template definition
b.doother(); // This must call the generic template definition
In other questions I saw people creating totally different specialization of the entire class. But I only want a specialization of a single method.
Upvotes: 2
Views: 358
Reputation: 217145
You can do what you want: http://ideone.com/oKTFPC
// Header
namespace My
{
template <typename T>
class MyClass {
public:
void dosome();
void doother();
};
template <typename T> void MyClass<T>::dosome() {}
template <typename T> void MyClass<T>::doother() {}
template<> void MyClass<char>::dosome();
}
// cpp or in header
template<>
void My::MyClass<char>::dosome() {
std::cout << "specialization" << std::endl;
}
or using alternate notation
namespace My {
template<>
void MyClass<char>::dosome() {
std::cout << "specialization" << std::endl;
}
}
Upvotes: 2
Reputation: 55395
One option would be tag dispatching:
template <typename T>
class MyClass {
public:
void dosome() { dosome_impl( T() ); }
private:
void dosome_impl(char) { /* char stuff */ }
template<typename U>
void dosome_impl(U) { /* usual stuff */ }
};
Another one is enable_if
idiom:
#include <type_traits>
template <typename T>
class MyClass {
public:
template<typename U = T>
typename std::enable_if<std::is_same<U,char>::value>::type
dosome() { /* char stuff */ }
template<typename U = T>
typename std::enable_if<!std::is_same<U,char>::value>::type
dosome() { /* normal stuff */ }
};
And yet another one is to move that single function to a base class that you can specialize:
template <typename T>
struct MyClass_base {
dosome() { /* usual stuff */ }
};
template<>
struct MyClass_base<char> {
dosome() { /* char stuff */ }
};
template <typename T>
class MyClass : private MyClass_Base<T> {
public:
// nothing special here
};
Upvotes: 2