Reputation: 1500
Is it possible to do something like the following that compiles without template specialization?
template <class T>
class A {
public:
#if std::is_same<T, int>
void has_int() { }
#elif std::is_same<T, char>
void has_char() { }
#endif
};
A<int> a; a.has_int();
A<char> b; b.has_char();
Upvotes: 13
Views: 14694
Reputation: 55415
Yes. Make the function templates and then conditionaly enable them using std::enable_if
:
#include <type_traits>
template <class T>
class A {
public:
template<typename U = T>
typename std::enable_if<std::is_same<U,int>::value>::type
has_int() {}
template<typename U = T>
typename std::enable_if<std::is_same<U,char>::value>::type
has_char() {}
};
int main()
{
A<int> a;
a.has_int(); // OK
// a.has_char(); // error
}
The solution from the other answer might not be feasible if the class is big and has got many functions that need to regardless of T
. But you can solve this by inheriting from another class that is used only for these special methods. Then, you can specialize that base class only.
In C++14, there are convenient type aliases so the syntax can become:
std::enable_if_t<std::is_same<U, int>::value>
And C++17, even shorter:
std::enable_if_t<std::is_same_v<U, int>>
Upvotes: 24
Reputation: 64253
Yes, with template specialization :
template <class T>
class A;
template <>
class A<int>
{
void had_int(){}
};
template <>
class A<char>
{
void had_char(){}
};
Upvotes: 6