вопрос по SFINAE и выбору функции
От: sergii.p  
Дата: 21.02.19 09:04
Оценка:
всем привет.
Попытался сделать простое разделение функций для enum и остальных типов и натолкнулся на не совсем понятные ошибки.
Для начала объявляю что-то типа концепции

template<typename T>
using IsEnumConcept = std::enable_if_t<std::is_enum<T>::value>;
template<typename T>
using IsNotEnumConcept = std::enable_if_t<!std::is_enum<T>::value>;


IsEnumConcept — для enum, IsNotEnumConcept — для всех остальных
Теперь пытаюсь сделать две функции, которые ничего не принимают (в реальности они принимают tuple, но для примера это не важно) и ничего не возвращают, но для enum они должны делать что-то отличное.

template<typename T, typename = IsEnumConcept<T>>
void out()
{
    cout<<"for enum\n";
}

template<typename T, typename = IsNotEnumConcept<T>>
void out()
{
    cout<<"for other\n";
}


в данном случае компилятор выдаёт ошибку redefinition of ‘template<class T, class> void out() Вроде ошибка вполне логичная и можно успокоиться, но немного переписываем пример

template<typename T>
IsEnumConcept<T> out()
{
    cout<<"for enum\n";
}

template<typename T>
IsNotEnumConcept<T> out()
{
    cout<<"for other\n";
}


и тут компилятор говорит, что всё ок, так дальше и пиши.
Во-первых, не понятно почему компилируется второй пример. Обе функции разворачиваются в void out() На лицо явное redefinition.
Во-вторых, не ясно, чем отличается первый пример от второго с точки зрения компилятора.

Первый вариант более читабелен, так что в приоритете. Хотелось бы его довести до рабочего состояния. На обоих компиляторах (студийный и gcc) поведение одинаковое, так что на них грешу в последнюю очередь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.