Шаблонная специализация с enable_if - PullRequest
3 голосов
/ 12 апреля 2019

Я пытаюсь создать шаблонную функцию, используя имя типа. Я хочу специализировать эти шаблоны для некоторых основных типов, таких как int, long, string и double. Для всех других типов мне нужен специальный код для класса / структуры и код по умолчанию для других типов.

Мой текущий код:

// 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;
}

Этот код не скомпилируется. Я не могу понять, что я должен написать в int специализированном шаблоне.

Я пытаюсь использовать примеры из этой документации , но я не могу заставить его работать.

Ответы [ 2 ]

5 голосов
/ 12 апреля 2019

typename enable_if<is_class<T>::value>::type = 0 не имеет смысла, потому что typename enable_if<is_class<T>::value>::type будет означать void; Вы можете изменить его на typename enable_if<is_class<T>::value>::type* = nullptr. Затем для полной специализации int обратите внимание, что test имеет два параметра шаблона, затем

// 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;
}

ЖИТЬ

Или просто укажите typename enable_if<is_class<T>::value>::type в качестве типа возврата. например,

// 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;
}

ЖИТЬ

0 голосов
/ 12 апреля 2019

Вам необходимо использовать std :: enable_if в аргументе функции вместо параметра шаблона:

// 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;
}
...