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
Inherited from std::integral_constant
Member constants
value [static] |
If T is an abstract class type, it is true, otherwise it is false(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 an abstract class type
std::is_abstract
template< class T > |
(C++11 onwards) |
If T
is an abstract class (that is, a non-union class type that declares or inherits at least one pure virtual function), provide a member constant value
equal to true. For other types, value
is false .
If T
is a non-union type, then T
should be a complete type; otherwise the behavior is undefined.
Template parameters
T | – | Type to check |
Auxiliary variable template
template< class T > |
(C++17 onwards) |
Call example
#include <iostream> #include <type_traits> struct A { int m; }; struct B { virtual void foo(); }; struct C { virtual void foo() = 0; }; struct D : C {}; int main() { std::cout << std::boolalpha; std::cout << "std::is_abstract<int>::value: " << std::is_abstract<int>::value << std::endl; std::cout << "std::is_abstract<double>::value: " << std::is_abstract<double>::value << std::endl; std::cout << "std::is_abstract<std::string>::value: " << std::is_abstract<std::string>::value << std::endl; std::cout << "std::is_abstract<A>::value: " << std::is_abstract<A>::value << std::endl; std::cout << "std::is_abstract<B>::value: " << std::is_abstract<B>::value << std::endl; std::cout << "std::is_abstract<C>::value: " << std::is_abstract<C>::value << std::endl; std::cout << "std::is_abstract<D>::value: " << std::is_abstract<D>::value << std::endl; return 0; }
Output
Check whether the type is a signed arithmetic type
std::is_signed
template< class T > |
(C++11 onwards) |
If T
is an arithmetic type and T(-1) < T(0)
, provide a member constant value
equal to true: this is true for floats Yields true
for dot types and signed integer types, and false
for unsigned integer types and bool
types.
For any other type, value
is false .
Template parameters
T | - | Type to check |
Auxiliary variable template
template< class T > |
(C++17 onwards) |
Possible implementation
namespace detail { template<typename T,bool = std::is_arithmetic<T>::value> struct is_signed : std::integral_constant<bool, T(-1) < T(0)> {}; template<typename T> struct is_signed<T,false> : std::false_type {}; } // namespace detail template<typename T> struct is_signed : detail::is_signed<T>::type {};
Call example
#include <iostream> #include <type_traits> class A {}; enum B : int {}; enum class C : int {}; int main() { std::cout << std::boolalpha; std::cout << "std::is_signed<A>::value: " << std::is_signed<A>::value << std::endl; std::cout << "std::is_signed<std::string>::value: " << std::is_signed<std::string>::value << std::endl; std::cout << "std::is_signed<float>::value: " << std::is_signed<float>::value << std::endl; std::cout << "std::is_signed<signed int>::value: " << std::is_signed<signed int>::value << std::endl; std::cout << "std::is_signed<unsigned int>::value: " << std::is_signed<unsigned int>::value << std::endl; std::cout << "std::is_signed<B>::value: " << std::is_signed<B>::value << std::endl; std::cout << "std::is_signed<C>::value: " << std::is_signed<C>::value << std::endl; // Short form: std::cout << "std::is_signed<signed int>(): " << std::is_signed<signed int>() << std::endl; std::cout << "std::is_signed<unsigned int>(): " << std::is_signed<unsigned int>() << std::endl; return 0; }
Output
Check whether the type is an unsigned arithmetic type
std::is_unsigned
template< class T > |
(C++11 onwards) |
If T
is an arithmetic type and T(0) < T(-1)
, then provide a member constant value
equal to true: this has no Yields true
for signed integer types and bool
types, and false
for signed integer and floating-point types.
For any other type, value
is false .
Template parameters
T | - | Type to check |
Auxiliary variable template
template< class T > |
(C++17 onwards) |
Possible implementation
namespace detail { template<typename T,bool = std::is_arithmetic<T>::value> struct is_unsigned : std::integral_constant<bool, T(0) < T(-1)> {}; template<typename T> struct is_unsigned<T,false> : std::false_type {}; } // namespace detail template<typename T> struct is_unsigned : detail::is_unsigned<T>::type {};
Call example
#include <iostream> #include <type_traits> class A {}; enum B : int {}; enum class C : int {}; int main() { std::cout << std::boolalpha; std::cout << "std::is_unsigned<A>::value: " << std::is_unsigned<A>::value << std::endl; std::cout << "std::is_unsigned<std::string>::value: " << std::is_unsigned<std::string>::value << std::endl; std::cout << "std::is_unsigned<float>::value: " << std::is_unsigned<float>::value << std::endl; std::cout << "std::is_unsigned<signed int>::value: " << std::is_unsigned<signed int>::value << std::endl; std::cout << "std::is_unsigned<unsigned int>::value: " << std::is_unsigned<unsigned int>::value << std::endl; std::cout << "std::is_unsigned<B>::value: " << std::is_unsigned<B>::value << std::endl; std::cout << "std::is_unsigned<C>::value: " << std::is_unsigned<C>::value << std::endl; // Short form: std::cout << "std::is_unsigned<signed int>(): " << std::is_unsigned<signed int>() << std::endl; std::cout << "std::is_unsigned<unsigned int>(): " << std::is_unsigned<unsigned int>() << std::endl; return 0; }