# std::is_function

< cpp‎ | types

定义于头文件 `<type_traits>` |  |
template< class T > struct is_function; |  | (C++11 起)

检查 `T` 是否为函数类型。如 std::function 、 lambda 、有重载 `operator()` 的类和指向函数指针不是函数类型。若 `T` 为函数类型，则提供等于 true 的成员常量 `value` 。否则， `value` 等于 false 。

添加 `is_function` 或 `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 [静态] | 若 `T` 为函数类型则为 true ，否则为 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
    > {};

下面展示的实现是为教学目的的，因为它会展现大量的函数类型种类。

### 可能的实现

    // 初等模板
    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 << std::is_function<A>::value << '\n';
        std::cout << std::is_function<int(int)>::value << '\n';
        std::cout << std::is_function<decltype(f)>::value << '\n';
        std::cout << std::is_function<int>::value << '\n';

        using T = PM_traits<decltype(&A::fun)>::member_type; // T 为 int() const&
        std::cout << std::is_function<T>::value << '\n';
    }

输出：

    false
    true
    true
    false
    true

### 参阅

is_invocable is_invocable_r is_nothrow_invocable is_nothrow_invocable_r (C++17) | 检查类型能否以给定的实参类型调用（如同以 std::invoke） (类模板)
is_object (C++11) | 检查是否是对象类型 (类模板)
is_class (C++11) | 检查类型是否非联合类类型 (类模板)