1022 Utilities Chapter 35 Type Property Predicates (continued) (§iso.20.9.4.3) is_nothrow_constructible<X,args> Can X be constructed from args using only noexcept operations? is_nothrow_default_constructible<X> is_nothrow_copy_constructible<X> is_nothrow_move_constructible<X> is_nothrow_assignable<X,Y> is_nothrow_copy_assignable<X> is_nothrow_move_assignable<X> is_nothrow_destructible<X> Does X have a virtual destructor? has_virtual_destructor<X> Like sizeof(T), a property query returns a numeric value related to a type argument: Type Property Queries (§iso.20.9.5) n=alignment_of<X> n=alignof(X) n=rank<X> n=extent<X,N> If X is an array, n is the number of dimensions; otherwise n==0 If X is an array, n is the number of elements in the Nth dimension; otherwise n==0 n=extent<X> n=extent<X,0> For example: template<typename T> void f(T a) { static_assert(Is_array<T>(), "f(): not an array"); constexpr int dn {Extent<a,2>()}; // the number of elements in the 2nd dimension (zero based) // .. } Here, I again used constexpr versions of the type functions returning numeric values (§28.2.2). The type relations are predicated on two types: Type Relations (§iso.20.9.6) is_same<X,Y> is_base_of<X,Y> is_convertible<X,Y> Is X the same type as Y? Is X a base of Y? Can an X be implicitly converted to a Y? For example: template<typename T> void draw(T t) { static_assert(Is_same<Shape ,T>() || Is_base_of<Shape,Remove_pointer<T>>(), ""); t−>draw(); } Section 35.4.2 Type Generators 1023 35.4.2 Type Generators In <type_traits>, the standard library provides type functions for producing a type given other types as arguments. const remove_const<X> remove_volatile<X> remove_cv<X> add_const<X> add_volatile<X> struct add_cv<X> and volatile Modification (§iso.20.9.7.1) Like X, but with any top-level const removed Like X, but with any top-level volatile removed Like X, but with any top-level const or volatile removed If X is a reference, function, or const, then X; otherwise const X If X is a reference, function, or volatile, then X; otherwise volatile X Add const and volatile: add_const<typename add_volatile<T>::type>::type A type transformer returns a type. To access that type, use the suffix ::type. For example: template<typename K, typename V> class My_map { { pair<typename add_const<K>::type,V> default_node; // ... }; If you tire of the ::type define a type alias (§28.2.1): template<typename T> using Add_const = typename add_const<T>::type; template<typename K, typename V> class My_map { { pair<Add_const<K>,V> default_node; // ... }; Ideally, use a support library that provides such aliases systematically for the standard-library type transformers. Reference Modification (§iso.20.9.7.2, §iso.20.9.7.6) remove_reference<X> add_lvalue_reference<X> add_rvalue_reference<X> decay<X> If X is a reference type, the referred-to type; otherwise, X If X is an rvalue reference Y&&, Y&; otherwise, X& If X is a reference, X; otherwise, X&& (§7.7.3) The type passed by value for a function argument of type X The decay functions handles array decay as well as reference dereferencing. The type functions for adding and removing references are important for when writing templates that should work with an argument that may be reference or not. For example: