std::is_function
Определено в заголовочном файле <type_traits>
|
||
template< class T > struct is_function; |
(начиная с C++11) | |
std::is_function
является UnaryTypeTrait.
Проверяет, является ли T
функциональным типом. Такие типы, как std::function, лямбда-выражения, классы с перегруженным operator()
и указатели на функции не считаются функциональными типами. Предоставляет константу-элемент value
, которая равна true, если T
является функциональным типом. Иначе value
равна false.
Поведение программы, добавляющей специализации для std::is_function
или std::is_function_v
(начиная с C++17) не определено.
Содержание |
[править] Параметры шаблона
T | — | тип для проверки |
[править] Шаблон вспомогательной переменной
template< class T > inline constexpr bool is_function_v = is_function<T>::value; |
(начиная с C++17) | |
Унаследован от std::integral_constant
Константы элементы
value [static] |
true, если T это функциональный тип, false иначе (public static константа-элемент) |
Функции-элементы
operator bool |
преобразует объект в bool, возвращает value (public функция-элемент) |
operator() (C++14) |
возвращает value (public функция-элемент) |
Типы элементы
Тип | Определение |
value_type
|
bool |
type
|
std::integral_constant<bool, value> |
[править] Примечание
std::is_function
можно реализовать очень просто. Реализации, подобные следующей, используются в новых версиях libc++, libstdc++ и MS STL:
template<class T> struct is_function : std::integral_constant< bool, !std::is_const<const T>::value && !std::is_reference<T>::value > {};
Реализация, показанная ниже, предназначена для учебных целей, поскольку она демонстрирует бесчисленное множество функциональных типов.
[править] Возможная реализация
// основной шаблон template<class> struct is_function : std::false_type { }; // специализация для обычных функций template<class Ret, class... Args> struct is_function<Ret(Args...)> : std::true_type {}; // специализация для функций с переменным числом аргументов, таких как std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {}; // специализация для функциональных типов, которые имеют cv-квалификаторы template<class Ret, class... Args> struct is_function<Ret(Args...) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile> : std::true_type {}; // специализация для функциональных типов, которые имеют ссылочные квалификаторы template<class Ret, class... Args> struct is_function<Ret(Args...) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &&> : std::true_type {}; // специализации для версий noexcept всего вышеперечисленного (C++17 и выше) template<class Ret, class... Args> struct is_function<Ret(Args...) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile && noexcept> : std::true_type {}; |
[править] Пример
#include <iostream> #include <type_traits> struct A { int fun() const&; }; template<typename> struct PM_traits {}; template<class T, class U> struct PM_traits<U T::*> { using member_type = U; }; int f(); int main() { std::cout << std::boolalpha; std::cout << "#1 " << std::is_function_v<A> << '\n'; std::cout << "#2 " << std::is_function_v<int(int)> << '\n'; std::cout << "#3 " << std::is_function_v<decltype(f)> << '\n'; std::cout << "#4 " << std::is_function_v<int> << '\n'; using T = PM_traits<decltype(&A::fun)>::member_type; // T является int() const& std::cout << "#5 " << std::is_function_v<T> << '\n'; }
Вывод:
#1 false #2 true #3 true #4 false #5 true
[править] Смотрите также
проверяет, может ли тип быть вызван (как если бы std::invoke) с заданными типами аргументов (шаблон класса) | |
(C++11) |
проверяет, является ли тип объектным типом (шаблон класса) |
(C++11) |
проверяет, является ли тип типом класса не объединения (шаблон класса) |