специализация шаблона с массивами, std :: is_array

Я играю с шаблонной специализацией и SFINAE.

Что касается следующего примера, все выглядит просто:

    template <class T>
void Do(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0)
{
cout << "is integer" << endl;
}

template <class T>
void Do(T t, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0)
{
cout << "is float" << endl;
}

Нет, я пробовал std :: is_array, но специализация с std :: is_array никогда не используется.

Поэтому я попробовал, почему is_array никогда не совпадает:

    template <int num>
void Do( int a[num])
{
cout << "int array size " << num << endl;
}

void Do( int* x)
{
cout << "int*" << endl;
}

...
int e[] = { 1,2,3 };
Do(e);
...

Первая загадка для мне в том, что специализация с «int a [num]» никогда не ловила! Параметр функции всегда имеет тип int *.

Если я использую ссылочные типы, я получаю «правильный» результат:

    template <int num>
void Do( int (&a)[num])
{
cout << "int array size " << num << endl;
}

void Do( int* &x)
{
cout << "int*" << endl;
}

Поэтому у меня возникает вопрос: есть ли разумное использование std :: is_array в сочетании с параметрами функции шаблона? я знаю это

    cout << boolalpha << std::is_array<decltype(e)>::value << endl;

даст мне правильный результат. Но объявление выбора шаблона вручную не дает мне функционального дополнения. Есть ли способ обнаружить (с или без SFINAE), что специализация шаблона из параметров функции соответствует массиву?

2

Решение

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

Причина, по которой вы хотите это сделать, — это затухание массива в указатель, которое является одним из немногих неявных преобразований, которые происходят с аргументами функции шаблона, прежде чем они будут сопоставлены с типами параметров. Вот почему T был указатель, когда вы пытались проверить, что это тип массива в DoIt, Однако распад массива на указатель делает не происходит, когда целевой тип является ссылочным типом. Итак, подведем итог:

template <class T>
void Do(T& t, typename std::enable_if<std::is_array<T>::value >::type* = 0)

должно сработать.

Кстати скучный способ не использовать SFINAE

template <class T, unsigned N>
void Do(T (&t)[N])

тоже работает

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]