std::is_function – std::is_function
Synopsis
Defined in header<type_traits>
template <class T>
(since C++ 11)
struct is_function;
Checks whether T is a function type. Types like std::function, lambdas, classes with overloaded operator() and pointers to functions don’t count as function types. Provides the member constant value which is equal to true, if T is a function type. Otherwise, value is equal to false.
Template parameters
T – a type to check
Helper variable template
template< class T > (since C++17)
inline constexpr bool is_function_v = is_function<T>::value;
Inherited from std::integral_constant
Member constants
value true if T is a function type , false otherwise
(public static member constant)
[static]
Member functions
converts the object to bool, returns value
operator bool (public member function)
operator() returns value
(public member function)
(C++14)
Member types
Type Definition
value_type bool
type std::integral_constant<bool, value>
Possible implementation
// 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 {};
Example
// Run this code
#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 is int() const&
std::cout << std::is_function<T>::value << '\n';
}
Output:
false
true
true
false
true
See also
is_invocable
is_invocable_r checks if a type can be invoked (as if by std::invoke) with the given argument types
is_nothrow_invocable (class template)
is_nothrow_invocable_r
(C++17)
is_object checks if a type is an object type
(class template)
(C++11)
is_class checks if a type is a non-union class type
(class template)
(C++11)