Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

SFINAE не работает :(

#cpp #cpp11 #шаблоны_с++ #cpp14


Почему не компилируется?

template 
class A {
    std::enable_if_t operator()() { return 1; }

    std::enable_if_t operator()() { return 2; }
};

    


Ответы

Ответ 1



SFINAE работает на уровне выведения аргументов шаблона функции, но Ваши функции (операторы) не являются шаблонными, поэтому разговора о SFINAE быть не может в принципе — ему тут неоткуда взяться. При любых раскладах у Вас в классе всегда будут 2 функции, одна из которых может быть валидна, а вторая, на контрасте с первой, будет невалидной. Но это если мы сделаем обе функции шаблонными, добавив некий фиктивный параметр шаблона. В текущей же редакции код просто-напросто невалиден в любом случае в силу того, что перегрузка нешаблонных функций по возвращаемому значению невозможна т.к. возвращаемый тип не является частью сигнатуры оной.

Ответ 2



SFINAE работает только для шаблонов (когда есть template непосредственно для сущности, для которой применяется SFINAE). Попробуйте так: template class A { template> value_type operator()() { return 1; } template> value_type operator()() { return 2; } }; Еще вариант, можно использовать частичную специализацию шаблона для класса template class A { value_type operator()() { return 2; } }; template class A <1, value_type> { value_type operator()() { return 1; } };

Ответ 3



Компилятор запрещает перегрузки с одинаковыми прототипами несмотря на SFINAE. Так что используйте вместо него обычное условие внутри функции. template class A { value_type operator()() { return (x == 1) ? 1 : 2; } }; Любой более-менее современный компилятор оптимизирует условия с участием констант (к которым относится и шаблонный параметр x).

Ответ 4



В 17 стандарте появится compile time if - именно то, что нужно в этой ситуации :)

Комментариев нет:

Отправить комментарий