std::is_function
From cppreference.com
Defined in header <type_traits> | ||
template<class T > struct is_function; | (since C++11) | |
std::is_function
is a UnaryTypeTrait.
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.
If the program adds specializations for std::is_function
or std::is_function_v
, the behavior is undefined.
Contents |
[edit]Template parameters
T | - | a type to check |
[edit]Helper variable template
template<class T > constexprbool is_function_v = is_function<T>::value; | (since C++17) | |
Inherited from std::integral_constant
Member constants
value [static] | true if T is a function type, false otherwise (public static member constant) |
Member functions
operator bool | converts the object to bool, returns value (public member function) |
operator() (C++14) | returns value (public member function) |
Member types
Type | Definition |
value_type | bool |
type | std::integral_constant<bool, value> |
[edit]Notes
std::is_function
can be implemented in much simpler ways. Implementations similar to the following one are used by new versions of libc++, libstdc++ and MS STL:
template<class T>struct is_function :std::integral_constant<bool, !std::is_const<const T>::value&&!std::is_reference<T>::value>{};
The implementation shown below is for pedagogical purposes, since it exhibits the myriad kinds of function types.
[edit]Possible implementation
// primary templatetemplate<class>struct is_function :std::false_type{}; // specialization for regular functionstemplate<class Ret, class... Args>struct is_function<Ret(Args...)>:std::true_type{}; // specialization for variadic functions such as std::printftemplate<class Ret, class... Args>struct is_function<Ret(Args......)>:std::true_type{}; // specialization for function types that have cv-qualifierstemplate<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...)constvolatile>: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......)constvolatile>:std::true_type{}; // specialization for function types that have ref-qualifierstemplate<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...)constvolatile&>: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......)constvolatile&>: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...)constvolatile&&>: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......)constvolatile&&>: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...)constnoexcept>:std::true_type{};template<class Ret, class... Args>struct is_function<Ret(Args...)volatilenoexcept>:std::true_type{};template<class Ret, class... Args>struct is_function<Ret(Args...)constvolatilenoexcept>:std::true_type{};template<class Ret, class... Args>struct is_function<Ret(Args......)constnoexcept>:std::true_type{};template<class Ret, class... Args>struct is_function<Ret(Args......)volatilenoexcept>:std::true_type{};template<class Ret, class... Args>struct is_function<Ret(Args......)constvolatilenoexcept>: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...)constvolatile&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......)constvolatile&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...)constvolatile&&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......)constvolatile&&noexcept>:std::true_type{}; |
[edit]Example
Run this code
#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 {staticint 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>);}
[edit]See also
checks if a type can be invoked (as if by std::invoke) with the given argument types (class template) | |
(C++11) | checks if a type is an object type (class template) |
(C++11) | checks if a type is a non-union class type (class template) |