#include <muu/strong_typedef.h>
template <typename ValueType, typename Tag, template<typename> typename... Traits>
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.