| std::is_function(3) | C++ Standard Libary | std::is_function(3) | 
NAME¶
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.
  
   The behavior of a program that adds specializations for is_function
  
   or is_function_v
  
   (since C++17) is undefined.
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
  
   [static] (public static member constant)
Member functions¶
 operator bool converts the object to bool, returns value
  
   (public member function)
  
   operator() returns value
  
   (C++14) (public member function)
Member types¶
 Type Definition
  
   value_type bool
  
   type std::integral_constant<bool, value>
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.
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 << "#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 is int()
    const&
  
   std::cout << "#5 " << std::is_function_v<T>
    << '\n';
  
   }
Output:¶
 #1 false
  
   #2 true
  
   #3 true
  
   #4 false
  
   #5 true
See also¶
 is_invocable
  
   is_invocable_r checks if a type can be invoked (as if by std::invoke) with
  
   is_nothrow_invocable the given argument types
  
   is_nothrow_invocable_r (class template)
  
   (C++17)
  
   is_object checks if a type is an object type
  
   (C++11) (class template)
  
   is_class checks if a type is a non-union class type
  
   (C++11) (class template)
| 2022.07.31 | http://cppreference.com |