Skip to main content

Boost.TypeTraits

Boost.TypeTraits provides a collection of compile-time type introspection and type transformation templates — is_integral, is_pointer, remove_const, add_reference, and dozens more. It was the direct ancestor of the <type_traits> header standardised in C++11, and remains relevant for the handful of traits the standard does not include.

The problem it solves

Generic code often needs to ask questions about types at compile time: "Is this an integer?" "Is this a pointer?" "What is this type without its const?" Before C++11, the language provided no built-in way to answer these questions. Boost.TypeTraits filled that gap and established the patterns that the standard later adopted wholesale.

Basic type queries

type_queries.cpp
#include <boost/type_traits.hpp>
#include <iostream>

int main() {
std::cout << std::boolalpha;
std::cout << boost::is_integral<int>::value << "\n"; // true
std::cout << boost::is_floating_point<double>::value << "\n"; // true
std::cout << boost::is_pointer<int*>::value << "\n"; // true
std::cout << boost::is_const<const int>::value << "\n"; // true
std::cout << boost::is_reference<int&>::value << "\n"; // true
std::cout << boost::is_class<std::string>::value << "\n"; // true
}

Type transformations

Transformation traits modify a type at compile time — stripping qualifiers, adding pointers, decaying function types.

type_transforms.cpp
#include <boost/type_traits.hpp>
#include <type_traits>

// Remove const
static_assert(std::is_same<
boost::remove_const<const int>::type,
int
>::value);

// Add pointer
static_assert(std::is_same<
boost::add_pointer<int>::type,
int*
>::value);

// Remove reference
static_assert(std::is_same<
boost::remove_reference<int&>::type,
int
>::value);

// Decay (array → pointer, function → function pointer, strip cv/ref)
static_assert(std::is_same<
boost::decay<const int(&)[5]>::type,
const int*
>::value);

SFINAE with enable_if

boost::enable_if (the predecessor of std::enable_if) lets you enable or disable template overloads based on compile-time type predicates.

sfinae.cpp
#include <boost/type_traits.hpp>
#include <boost/core/enable_if.hpp>
#include <iostream>

// Only enabled for integral types
template <typename T>
typename boost::enable_if<boost::is_integral<T>, T>::type
twice(T x) {
return x * 2;
}

// Only enabled for floating-point types
template <typename T>
typename boost::enable_if<boost::is_floating_point<T>, T>::type
twice(T x) {
return x * 2.0;
}

int main() {
std::cout << twice(5) << "\n"; // 10
std::cout << twice(2.5) << "\n"; // 5.0
}
Modern alternative

In C++17 and later, prefer if constexpr over SFINAE for most conditional compilation. It is dramatically easier to read and produces better error messages.

Composite type traits

Boost provides traits that classify types into broader categories, useful for writing generic containers and algorithms.

composite.cpp
#include <boost/type_traits.hpp>
#include <vector>

// is_arithmetic = is_integral || is_floating_point
static_assert(boost::is_arithmetic<int>::value);
static_assert(boost::is_arithmetic<double>::value);

// is_fundamental = is_arithmetic || is_void
static_assert(boost::is_fundamental<void>::value);

// is_compound = !is_fundamental
static_assert(boost::is_compound<std::vector<int>>::value);

Relationship traits

relationships.cpp
#include <boost/type_traits.hpp>

struct Base {};
struct Derived : Base {};

static_assert(boost::is_base_of<Base, Derived>::value);
static_assert(boost::is_convertible<Derived*, Base*>::value);
static_assert(boost::is_same<int, int>::value);

Boost.TypeTraits versus std type_traits

Featureboost::std:: (C++11+)
Header<boost/type_traits.hpp><type_traits>
Core traitsidentical interfaceidentical interface
_v shorthandnoyes (C++17): is_integral_v<T>
_t aliasnoyes (C++14): remove_const_t<T>
Extra traitshas_plus, has_nothrow_assign, ...not provided
Pre-C++11yesno
Which to choose

On C++11 and later, prefer std:: type traits — they have the _v and _t conveniences and need no dependency. Use boost:: only for the extra traits not in the standard (has_plus, has_trivial_copy, etc.) or when targeting a pre-C++11 compiler. See Boost and the C++ Standard for the full lineage.

Common patterns

See also