Type attributes
A type attribute defines a compile-time template-based structure for querying or modifying the properties of a type.
Attempting to specialize a template defined in the
Templates defined in the
Type attribute
Defined in header file
Basic type categories
Inherited from std::integral_constant
Member constants
value [static] |
True if T is a union type, false otherwise(Public static member constants) |
Member functions
operator bool |
Convert the object to bool and return value (Public member function) |
operator() (C++14) |
Return value (Public member function) |
Member type
Type | Definition |
value_type |
bool |
type |
std::integral_constant |
Check whether the type is a union type
std::is_union
template< class T > |
(C++11 onwards) |
Checks whether T
is a union type. If T
is a union type, provide the member constant value
equal to true. Otherwise value
, equal to false .
Template parameters
T | – | Type to check |
Auxiliary variable template
template< class T > |
(C++17 onwards) |
Check whether the type is not a union type
std::is_class
template< class T > |
(C++11 onwards) |
Checks whether T
is a non-union class type. If T
is a class type (but not a union), provide a member constant value
equal to true. Otherwise, value
is equal to false .
Note that the type declared with the struct
keyword is a class, so this attribute is true for “structure”.
Template parameters
T | – | Type to check |
Auxiliary variable template
template< class T > |
Possible implementation
namespace detail { template <class T> char test(int T::*); struct two { char c[2]; }; template <class T> two test(...); } template <class T> struct is_class : std::integral_constant<bool, sizeof(detail::test<T>(0))==1 & amp; & amp; !std::is_union<T>::value> {};
Check whether it is a function type
std::is_function
template< class T > |
(C++11 onwards) |
Checks whether T
is a function type. For example, std::function, lambda, classes with overloaded operator()
and pointers to functions are not function types. If T
is a function type, provide member constant value
equal to true. Otherwise, value
is equal to false .
Template parameters
T | – | Type to check |
Auxiliary variable template
template< class T > |
(C++17 onwards) |
Possible implementation
//Elementary template template<class> struct is_function : std::false_type { }; //Specialization of regular functions template<class Ret, class... Args> struct is_function<Ret(Args...)> : std::true_type {}; // Specializations for variadic functions such as std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {}; // Specialization for function types with cv qualifier 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 of function types with reference qualifiers template<class Ret, class... Args> struct is_function<Ret(Args...) & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile & amp; & amp;> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile & amp; & amp;> : std::true_type {}; // Specializations for all noexcept versions 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...) & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & amp; & amp; noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile & amp; & amp; noexcept> : std::true_type {};
Call example
#include <iostream> #include <type_traits> struct A {}; typedef union { int a; float b; } B; struct C { B d; }; enum E {}; enum class Ec : int {}; struct D { 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_union<A>::value: " << std::is_union<A>::value << std::endl; std::cout << "std::is_union<B>::value: " << std::is_union<B>::value << std::endl; std::cout << "std::is_union<C>::value: " << std::is_union<C>::value << std::endl; std::cout << "std::is_union<int>::value: " << std::is_union<int>::value << std::endl; std::cout << "std::is_union<float>::value: " << std::is_union<float>::value << std::endl; std::cout << std::endl; std::cout << "std::is_class<A>::value: " << std::is_class<A>::value << std::endl; std::cout << "std::is_class<B>::value: " << std::is_class<B>::value << std::endl; std::cout << "std::is_class<C>::value: " << std::is_class<C>::value << std::endl; std::cout << "std::is_class<int>::value: " << std::is_class<int>::value << std::endl; std::cout << "std::is_class<float>::value: " << std::is_class<float>::value << std::endl; std::cout << std::endl; std::cout << "std::is_function<A>::value: " << std::is_function<A>::value << std::endl; std::cout << "std::is_function<int(int)>::value: " << std::is_function<int(int)>::value << std::endl; std::cout << "std::is_function<decltype(f)>::value: " << std::is_function<decltype(f)>::value << std::endl; std::cout << "std::is_function<int>::value: " << std::is_function<int>::value << std::endl; using T = PM_traits<decltype( & amp;D::fun)>::member_type; // T is int() const & amp; std::cout << "std::is_function<T>::value: " << std::is_function<T>::value << std::endl; std::cout << std::endl; return 0; }