template <typename ValueType, typename Tag, template<typename> typename... Traits>
muu::strong_typedef struct

A utility class for creating 'strong typedefs'.

Template parameters
ValueType The underlying value type held by the typedef object. May be a reference. May not be cv-qualified unless it is also a reference.
Tag The tag type necessary to uniquely identify this typedef. May be an incomplete type.
Traits Additional CRTP-based 'traits' for adding custom functionality.

Strong typedefs use the C++ type system to create compile-time guarantees for values that otherwise might only be represented by regular typedefs, and thus lose their semantic meaning when passed to the compiler. Doing so prevents an entire class of bugs where incompatible values can be accidentally used interchangeably because they were of same/convertible type:

#ifdef DO_BAD_STUFF
using thing_id    = int;
using thing_index = int;
#else
using thing_id    = muu::strong_typedef<int, struct thing_id_tag>;
using thing_index = muu::strong_typedef<int, struct thing_index_tag>;
#endif

void do_important_stuff(thing_id id)
{
    //
}

void this_function_does_bad_stuff(thing_index index)
{
    do_important_stuff(index); // won't compile with strong typedefs
}

By default the only operations provided are:

  • explicit construction with an initializer
  • default construction (if supported by the value type)
  • copy construction + assignment (if supported by the value type)
  • move construction + assignment (if supported by the value type)
  • explicit casts to references of the underlying value type
using strong_string = muu::strong_typedef<std::string, struct strong_string_tag>;

strong_string s{ "my string could beat up your string"s };
auto& ref = static_cast<std::string&>(s);

Additional operations can be added using CRTP-based 'traits':

using thing_index = muu::strong_typedef<int, struct thing_index_tag,
    muu::strong_typedef_traits::incrementable, // adds ++
    muu::strong_typedef_traits::decrementable, // adds --
    muu::strong_typedef_traits::comparable     // adds ==, !=, <, <=, >, >=
>;

Public types

using value_type = ValueType
The typedef's underlying value type.

Constructors, destructors, conversion operators

strong_typedef() defaulted
Default constructor.
strong_typedef(const strong_typedef&) defaulted constexpr
Copy constructor.
strong_typedef(strong_typedef&&) defaulted constexpr
Move constructor.
strong_typedef(const value_type& val) explicit constexpr noexcept(…)
Value copy constructor.
strong_typedef(value_type&& val) explicit constexpr noexcept(…)
Value move constructor.
strong_typedef(value_type val) explicit constexpr noexcept
Value constructor.

Public functions

auto operator=(const strong_typedef&) -> strong_typedef& defaulted
Copy-assignment operator.
auto operator=(strong_typedef&&) -> strong_typedef& defaulted
Move-assignment operator.

Public variables

value_type value
The underlying value stored in the typedef.