I am trying to construct some kind of "generic type alias", meaning I want to define a type as int
for example, but with a generic type argument which then makes it incompatible with instances of other types.
I tried doing this with alias templates:
template <typename T>
using NumberWithSemantics = int;
But the problem with this is that all instantiations, no matter the type T
, are considered equal, for example:
struct A {};
struct B {};
NumberWithSemantics<A> getThing() {
return 14;
}
int processDifferentThing(NumberWithSemantics<B> b) {
return b * 3;
}
int main() {
auto a = getThing();
return processDifferentThing(a); // unfortunately compiles just fine
}
Is there a way to define some kind of generic type alias that disallows mixing different template instantiations?
C++ has type aliasing, but it is only weak type aliasing. When you say
typedef int MyType;
or
using MyType = int;
you tell the compiler, “whenever you see MyType
, pretend you had just seen int
instead”. There is then no difference at all between MyType i
and int i
; both create a variable named i
of type int
. Making the using
declaration a template doesn’t help; all of the types equivalently mean int
.
What you want to do is create an actual new type. To do this, you need to declare it with struct
or class
, not just using
. Even if they look the same, the type system will treat each new type created this way as a separate type; by extension, if you make a template struct
, each instantiation will be a new type.
Therefore, the minimum potential solution would be:
template <typename T>
struct NumberWithSemantics { int i; };
Then you can use NumberWithSemantics<A>
and NumberWithSemantics<B>
as different types. However, you will need to keep saying .i
to get the actual value out, which can make your code harder to read. There are various possible ways to get around that, for which I recommend reading this part of the Strong Types series on Fluent C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With