Я спрашиваю об одном (популярном) вопросе - обнаружении существования метода класса.
Я прочитал много ответов здесь в 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.