Spec-Zone.ru › C++

std::is_function

Определён в заголовочном файле <type_traits>
template< class T >
struct is_function;
(начиная с C++11)

std::is_function — это унарный типовой признак.

Проверяет, является ли T типом функции. Типы вроде std::function, лямбда-выражения, классы с перегруженным operator() и указатели на функции не считаются типами функций. Предоставляет константу-член value, равную true, если T является типом функции. В противном случае value равно false.

Если программа добавляет специализации для std::is_function или std::is_function_v, поведение не определено.

Параметры шаблона

T - тип для проверки

Вспомогательный шаблон переменной

template< class T >
constexpr bool is_function_v = is_function<T>::value;
(начиная с C++17)

Унаследовано от std::integral_constant

Константы-члены

value
[static]
true, если T является типом функции, иначе false
(открытая статическая константа-член)

Функции-члены

operator bool
преобразует объект в bool, возвращает value
(открытая функция-член)
operator()
(C++14)
возвращает value
(открытая функция-член)

Типы-члены

Тип Определение
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
> {};

Приведённая ниже реализация предназначена для обучения, поскольку демонстрирует множество разновидностей типов функций.

Возможная реализация

// primary template
template<class>
struct is_function : std::false_type {};

// specialization for regular functions
template<class Ret, class... Args>
struct is_function<Ret(Args...)> : std::true_type {};

// specialization for variadic functions such as std::printf
template<class Ret, class... Args>
struct is_function<Ret(Args......)> : std::true_type {};

// specialization for function types that have cv-qualifiers
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 {};

// specialization for function types that have ref-qualifiers
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 {};

// specializations for noexcept versions of all the above (C++17 and later)
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 <functional>
#include <type_traits>

int f();
static_assert(std::is_function_v<decltype(f)>);

static_assert(std::is_function_v<int(int)>);
static_assert(!std::is_function_v<int>);
static_assert(!std::is_function_v<decltype([]{})>);
static_assert(!std::is_function_v<std::function<void()>>);

struct O { void operator()() {} };
static_assert(std::is_function_v<O()>);

struct A
{
    static int foo();
    int fun() const&;
};
static_assert(!std::is_function_v<A>);
static_assert(std::is_function_v<decltype(A::foo)>);
static_assert(!std::is_function_v<decltype(&A::fun)>);

template<typename>
struct PM_traits {};
template<class T, class U>
struct PM_traits<U T::*> { using member_type = U; };

int main()
{
    using T = PM_traits<decltype(&A::fun)>::member_type; // T is int() const&
    static_assert(std::is_function_v<T>);
}

См. также

is_invocableis_invocable_ris_nothrow_invocableis_nothrow_invocable_r
(C++17)(C++17)(C++17)(C++17)
проверяет, можно ли вызвать тип (как если бы использовался std::invoke) с заданными типами аргументов
(шаблон класса)
is_object
(C++11)
проверяет, является ли тип объектным типом
(шаблон класса)
is_class
(C++11)
проверяет, является ли тип типом класса, не являющегося объединением
(шаблон класса)
is_function_type
(C++26)
проверяет, является ли отражённый тип типом функции
(функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/types/is_function

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API