Пространства имён
Варианты
Действия

std::is_function

Материал из cppreference.com
< cpp‎ | types
 
 
Библиотека метапрограммирования
Свойства типов
Категории типов
(C++11)
(C++14)  
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
is_function
(C++11)
(C++11)
(C++11)
Свойства типов
(C++11)
(C++11)
(C++14)
(C++11)
(C++11)(до C++20*)
(C++11)(устарело в C++20)
(C++11)
Константы свойств типа
Метафункции
(C++17)
Поддерживаемые операции
Запросы отношений и свойств
Модификации типов
(C++11)(C++11)(C++11)
Преобразования типов
(C++11)(устарело в C++23)
(C++11)(устарело в C++23)
(C++11)
(C++11)
(C++17)

(C++11)(до C++20*)(C++17)
Рациональная арифметика времени компиляции
Целочисленные последовательности времени компиляции
 
Определено в заголовочном файле <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)
проверяет, является ли тип типом класса не объединения
(шаблон класса) [править]