Predefined Concepts - Part I

The golden rule “Don’t reinvent the wheel” also applies to concepts. The C++ Core Guidelines are very clear about this rule:

T.11: Whenever possible use standard concepts.

Consequently, I want to give you an overview of the important predefined concepts. I intentionally ignore any special or auxiliary concepts.

All predefined concepts are detailed in the latest C++20 working draft, N4860, and finding them all can be quite a challenge! Most of the concepts are in the concepts library and ranges library. Additionally, a few concepts are in the language support library, general utilities library, iterators library, and numerics library. The C++20 draft N4860 also has an index to all library concepts and shows how the concepts are implemented.

Language support library

This section discusses an interesting concept, three_way_comparable. It is used to support the three-way comparison operator. It is specified in the header <compare>. More formally, let a and b be values of type T. These values are three_way_comparable only if:

  • (a <=> b == 0) == bool(a == b) is true
  • (a <=> b != 0) == bool(a != b) is true
  • ((a <=> b) <=> 0) and (0 <=> (b <=> a)) are equal
  • (a <=> b < 0) == bool(a < b) is true
  • (a <=> b > 0) == bool(a > b) is true
  • (a <=> b <= 0) == bool(a <= b) is true
  • (a <=> b >= 0) == bool(a >= b) is true

Concepts library

The most frequently used concepts can be found in the concepts library. They are defined in the <concepts> header.

Language-related concepts

This section has about 1515 concepts that should be self-explanatory. These concepts express relationships between types, type classifications, and fundamental type properties. Their implementation is often directly based on the corresponding function from the type-traits library. Where deemed necessary, I provide additional explanation.

  • same_as
  • derived_from
  • convertible_to
  • common_reference_with: common_reference_with<T, U> must be valid, and T and U must be convertible to a reference type C where C is the same as common_reference_t<T, U>
  • common_with: similar to common_reference_with, but the common type C is the same as common_type_t<T, U> and may not be a reference type
  • assignable_from
  • swappable

Arithmetic concepts

  • integral
  • signed_integral
  • unsigned_integral
  • floating_point

The standard’s definition of the arithmetic concepts is straightforward:

template <class T>
concept integral = is_integral_v<T>;

template <class T>
concept signed_integral = integral<T> && is_signed_v<T>;

template <class T>
concept unsigned_integral = integral<T> && !signed_integral<T>;

template <class T>
concept floating_point = is_floating_point_v<T>;

Get hands-on with 1400+ tech skills courses.