| Home | Libraries | People | FAQ | More

### Type Traits by Category

#### Type Traits that Describe the Properties of a Type

These traits are all value traits, which is to say the traits classes all inherit from integral_constant, and are used to access some numerical property of a type. Often this is a simple true or false Boolean value, but in a few cases may be some other integer value (for example when dealing with type alignments, or array bounds: see `alignment_of`, `rank` and `extent`).

##### Categorizing a Type

These traits identify what "kind" of type some type `T` is. These are split into two groups: primary traits which are all mutually exclusive, and composite traits that are compositions of one or more primary traits.

For any given type, exactly one primary type trait will inherit from true_type, and all the others will inherit from false_type, in other words these traits are mutually exclusive.

This means that `is_integral<T>::value` and `is_floating_point<T>::value` will only ever be true for built-in types; if you want to check for a user-defined class type that behaves "as if" it is an integral or floating point type, then use the `std::numeric_limits template` instead.

Synopsis:

    template <class T>
    struct is_array<T>;

    template <class T>
    struct is_class<T>;

    template <class T>
    struct is_enum<T>;

    template <class T>
    struct is_floating_point<T>;

    template <class T>
    struct is_function<T>;

    template <class T>
    struct is_integral<T>;

    template <class T>
    struct is_member_function_pointer<T>;

    template <class T>
    struct is_member_object_pointer<T>;

    template <class T>
    struct is_pointer<T>;

    template <class T>
    struct is_reference<T>;

    template <class T>
    struct is_union<T>;

    template <class T>
    struct is_void<T>;

The following traits are made up of the union of one or more type categorizations. A type may belong to more than one of these categories, in addition to one of the primary categories.

    template <class T>
    struct is_arithmetic;

    template <class T>
    struct is_compound;

    template <class T>
    struct is_fundamental;

    template <class T>
    struct is_member_pointer;

    template <class T>
    struct is_object;

    template <class T>
    struct is_scalar;

##### General Type Properties

The following templates describe the general properties of a type.

Synopsis:

    template <class T>
    struct alignment_of;

    template <class T>
    struct has_nothrow_assign;

    template <class T>
    struct has_nothrow_constructor;

    template <class T>
    struct has_nothrow_copy;

    template <class T>
    struct has_trivial_assign;

    template <class T>
    struct has_trivial_constructor;

    template <class T>
    struct has_trivial_copy;

    template <class T>
    struct has_trivial_destructor;

    template <class T>
    struct has_virtual_destructor;

    template <class T>
    struct is_abstract;

    template <class T>
    struct is_const;

    template <class T>
    struct is_empty;

    template <class T>
    struct is_stateless;

    template <class T>
    struct is_pod;

    template <class T>
    struct is_polymorphic;

    template <class T>
    struct is_volatile;

    template <class T, std::size_t N = 0>
    struct extent;

    template <class T>
    struct rank;

##### Relationships Between Two Types

These templates determine the whether there is a relationship between two types:

Synopsis:

    template <class Base, class Derived>
    struct is_base_of;

    template <class From, class To>
    struct is_convertible;

    template <class T, class U>
    struct is_same;

#### Type Traits that Transform One Type to Another

The following templates transform one type to another, based upon some well-defined rule. Each template has a single member called `type` that is the result of applying the transformation to the template argument `T`.

Synopsis:

    template <class T>
    struct add_const;

    template <class T>
    struct add_cv;

    template <class T>
    struct add_pointer;

    template <class T>
    struct add_reference;

    template <class T>
    struct add_volatile;

    template <class T>
    struct remove_all_extents;

    template <class T>
    struct remove_const;

    template <class T>
    struct remove_cv;

    template <class T>
    struct remove_extent;

    template <class T>
    struct remove_pointer;

    template <class T>
    struct remove_reference;

    template <class T>
    struct remove_volatile;

#### Broken Compiler Workarounds:

For all of these templates support for partial specialization of class templates is required to correctly implement the transformation. On the other hand, practice shows that many of the templates from this category are very useful, and often essential for implementing some generic libraries. Lack of these templates is often one of the major limiting factors in porting those libraries to compilers that do not yet support this language feature. As some of these compilers are going to be around for a while, and at least one of them is very wide-spread, it was decided that the library should provide workarounds where possible.

The basic idea behind the workaround is to manually define full specializations of all type transformation templates for all fundamental types, and all their 1st and 2nd rank cv-[un]qualified derivative pointer types, and to provide a user-level macro that will define all the explicit specializations needed for any user-defined type T.

The first part guarantees the successful compilation of something like this:

    BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));
    ...
    BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));

and the second part provides the library's users with a mechanism to make the above code work not only for `char`, `int` or other built-in type, but for they own types as well:

    namespace myspace{
       struct MyClass {};
    }
    // declare this at global scope:
    BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(myspace::MyClass)
    // transformations on myspace::MyClass now work:
    BOOST_STATIC_ASSERT((is_same<myspace::MyClass, remove_reference<myspace::MyClass&>::type>::value));
    BOOST_STATIC_ASSERT((is_same<myspace::MyClass, remove_const<myspace::MyClass const>::type>::value));
    // etc.

Note that the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to nothing on those compilers that do support partial specialization.

#### Synthesizing Types with Specific Alignments

Some low level memory management routines need to synthesize a POD type with specific alignment properties. The template `type_with_alignment` finds the smallest type with a specified alignment, while template `aligned_storage` creates a type with a specific size and alignment.

Synopsis

    template <std::size_t Align>
    struct type_with_alignment;

    template <std::size_t Size, std::size_t Align>
    struct aligned_storage;

#### Decomposing Function Types

The class template function_traits extracts information from function types (see also is_function). This traits class allows you to tell how many arguments a function takes, what those argument types are, and what the return type is.

Synopsis

    template <std::size_t Align>
    struct function_traits;

| Copyright © 2000, 2005 Adobe Systems Inc, David Abrahams, Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Thorsten Ottosen, Robert Ramey and Jeremy Siek