Как обнаружить метод noexcept с помощью SFINAE

Я спрашиваю о варианте (популярного) вопроса - обнаружении существования метода класса.

Я прочитал много ответов здесь, в SO, и большинство решений (после С++ 17) выглядят как это:

#include <type_traits>

template<class ...Ts>
struct voider{
    using type = void;
};

template<class T, class = void>
struct has_foo : std::false_type{};

template<class T>
struct has_foo<T, typename voider<decltype(std::declval<T>().foo())>::type> : std::true_type{};

По сути, мы позволяем компилятору решить, используя «трюк»: если выражение std::declval<T>().foo() правильно сформировано, то decltype(std::declval<T>().foo()) не выдает ошибку компиляции, тогда компилятор «предпочитает» has_foo<T, typename voider<decltype(...)>>::type, поскольку ему не нужно заменять второй тип шаблона с типом по умолчанию.

отлично, но как мы можем совместить с ним noexcept? Я пробовал много способов, но кажется, что большинство методов (включая decltype(declval<type>.my_func())) заботятся только об имени, типе возвращаемого значения и типах аргументов, а не о исключении.


person David Haim    schedule 25.01.2020    source источник
comment
Почему бы тогда просто не использовать оператор noexcept?   -  person ezegoing    schedule 25.01.2020


Ответы (1)


Вы можете сделать это с помощью оператора noexpect (начиная с C++11 ).

Оператор noexcept выполняет проверку во время компиляции, которая возвращает true, если объявлено, что выражение не вызывает никаких исключений.

e.g.

template<class T>
struct has_foo<T, 
               typename voider<decltype(std::declval<T>().foo()),
                               std::enable_if_t<noexcept(std::declval<T>().foo())>
                              >::type
              > : std::true_type{};

ПРЯМОЙ ЭФИР

person songyuanyao    schedule 25.01.2020