Reputation: 15104
I'm trying to create a template function taking a typename. I want to specialize this templates for some basic types like int
, long
, string
and double
. For all others types, i need to have a specialized code for class/struct, and a default code for others types.
My current code is this one :
// Declaration
template <typename T, typename enable_if<is_class<T>::value>::type = 0>
void test(T& value);
template <typename T, typename enable_if<!is_class<T>::value>::type = 0>
void test(T& value);
template <> // What am i supposed to write here ?
void test<int>(int& value);
// Definition
template <typename T, typename enable_if<is_class<T>::value>::type = 0>
void test(T& value) {
cout << "Class/struct test" << endl;
}
template <typename T, typename enable_if<!is_class<T>::value>::type = 0>
void test(T& value) {
cout << "Other types test" << endl;
}
template <>
void test<int>(int& value) {
cout << "int test" << endl;
}
This code won't compile. I can't figure what am i suppoed to write in the int
specialized template.
I'm trying to use the examples from this documentation, but i'm unable to make it work.
Upvotes: 5
Views: 1746
Reputation: 172864
typename enable_if<is_class<T>::value>::type = 0
doesn't make sense, because typename enable_if<is_class<T>::value>::type
would refer to void
; you can change it to typename enable_if<is_class<T>::value>::type* = nullptr
. Then for the full specialization for int
, note that test
has two template parameters, then
// Declaration
template <typename T, typename enable_if<is_class<T>::value>::type* = nullptr>
void test(T& value);
template <typename T, typename enable_if<!is_class<T>::value>::type* = nullptr>
void test(T& value);
template <>
void test<int, nullptr>(int& value);
// Definition
template <typename T, typename enable_if<is_class<T>::value>::type*>
void test(T& value) {
cout << "Class/struct test" << endl;
}
template <typename T, typename enable_if<!is_class<T>::value>::type*>
void test(T& value) {
cout << "Other types test" << endl;
}
template <>
void test<int, nullptr>(int& value) {
cout << "int test" << endl;
}
Or simply put typename enable_if<is_class<T>::value>::type
as the return type. e.g.
// Declaration
template <typename T>
typename enable_if<is_class<T>::value>::type test(T& value);
template <typename T>
typename enable_if<!is_class<T>::value>::type test(T& value);
template <>
void test<int>(int& value);
// Definition
template <typename T>
typename enable_if<is_class<T>::value>::type test(T& value) {
cout << "Class/struct test" << endl;
}
template <typename T>
typename enable_if<!is_class<T>::value>::type test(T& value) {
cout << "Other types test" << endl;
}
template <>
void test<int>(int& value) {
cout << "int test" << endl;
}
Upvotes: 6
Reputation: 2324
You need to use std::enable_if in function argument instead of a template parameter:
// Declaration
template <typename T>
void test(T& value, enable_if_t<is_class<T>::value>* = nullptr);
template <typename T>
void test(T& value, enable_if_t<!is_class<T>::value>* = nullptr);
template <>
void test<int>(int& value, enable_if_t<!is_class<int>::value>*);
// Definition
template <typename T>
void test(T& value, enable_if_t<is_class<T>::value>*){
cout << "Class/struct test" << endl;
}
template <typename T>
void test(T& value, enable_if_t<!is_class<T>::value>*) {
cout << "Other types test" << endl;
}
template <>
void test<int>(int& value, enable_if_t<!is_class<int>::value>*) {
cout << "int test" << endl;
}
Upvotes: 0