Как обнаружить метод noexcept, используя SFINAE - PullRequest
2 голосов
/ 25 января 2020

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

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

#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())) заботятся только об имени, типе возвращаемого значения и типах аргументов, а не о noexcept.

1 Ответ

3 голосов
/ 25 января 2020

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

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

например,

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

LIVE

...