Информация об изменениях

Сообщение Re: вопрос по SFINAE и выбору функции от 21.02.2019 17:25

Изменено 21.02.2019 17:25 rg45

Re: вопрос по SFINAE и выбору функции
Здравствуйте, sergii.p, Вы писали:

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


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

https://ideone.com/9yYOUz

#include <iostream>

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

template<typename T, typename = void>
struct OutImpl;

template <typename T>
struct OutImpl<T, IsEnumConcept<T>>
{
    void operator()() const { std::cout<<"for enum\n"; }    
};

template <typename T>
struct OutImpl<T, IsNotEnumConcept<T>>
{
    void operator()() const { std::cout<<"for not enum\n"; }    
};

template<typename T>
void out()
{
    OutImpl<T>()();
}

enum class MyEnum{};

int main() {
    out<MyEnum>();
    out<int>();
}
Re: вопрос по SFINAE и выбору функции
Здравствуйте, sergii.p, Вы писали:

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


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

https://ideone.com/9yYOUz

#include <iostream>

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

template<typename T, typename = void>
struct OutImpl;

template <typename T>
struct OutImpl<T, IsEnumConcept<T>>
{
    void operator()() const { std::cout<<"for enum\n"; }    
};

template <typename T>
struct OutImpl<T, IsNotEnumConcept<T>>
{
    void operator()() const { std::cout<<"for not enum\n"; }    
};

template<typename T>
void out()
{
    OutImpl<T>()();
}

enum class MyEnum{};

int main() {
    out<MyEnum>();
    out<int>();
}