I had a similar case where I wanted to distinguish different meanings of some integer values, and forbid implicit conversions between them. I wrote a generic class like this:
template <typename T, typename Meaning>
struct Explicit
{
//! Default constructor does not initialize the value.
Explicit()
{ }
//! Construction from a fundamental value.
Explicit(T value)
: value(value)
{ }
//! Implicit conversion back to the fundamental data type.
inline operator T () const { return value; }
//! The actual fundamental value.
T value;
};
Of course if you want to be even more safe, you can make the T
constructor explicit
as well. The Meaning
is then used like this:
typedef Explicit<int, struct EntityIDTag> EntityID;
typedef Explicit<int, struct ModelIDTag> ModelID;