0 day streak
cpp / expert
Snippet

Strong Identity Wrapping via Phantom Types

Leveraging template tags to create distinct, incompatible types from a single primitive. This enforces domain logic at the type level, preventing accidental data mixing.

snippet.cpp
cpp
1
2
3
4
5
6
7
8
9
10
11
template <typename T, typename Tag>
struct Identity {
explicit Identity(T value) : val(value) {}
T val;
};
using UserId = Identity<int, struct UserTag>;
using OrderId = Identity<int, struct OrderTag>;
void process(UserId id) {}
// UserId u(1); OrderId o(1); process(o); // Error!
Breakdown
1
template <typename T, typename Tag>
The Tag parameter acts as a 'phantom type' to distinguish instances.
2
explicit Identity(T value)
Prevents implicit conversion from the raw underlying type.
3
using UserId = Identity<int, struct UserTag>;
Defines a unique type for User IDs using an anonymous struct tag.