I would like to create lightweight types that encapsulate a primitive numerical type:
struct A { long value; }
struct B { long value; }
struct C { long value; }
...
so that I can apply the usual arithmetic operations to each type, with the expected results (and without any run-time overhead in comparison with the built-in type long):
A a1 {10};
A a2 {20};
A a3 = a1 + a2:
++a3;
std::cout << a3; // prints "31"
...
However, I do not want any (automatic) conversions between different types, and I do not want to allow any arithmetic operations that mix different types. For example, the following code should not compile:
A a1 {10};
A a2 {20};
B b3 = a1 + a2: // error, cannot convert A to B
a2 += b3; // error, A::operator+=(B) does not exist
...
Now all of this would be straightforward if I just wanted a single type; just define the appropriate operations for class A. However, it gets soon tedious if I try to do the same for classes A, B, C, ... etc. that only differ in the name.
I know that I could use preprocessor macros to generate multiple copies with different names. However, I was wondering if there is a more elegant approach that does not use preprocessor, and does not require any duplicated code. (C++11 specific solutions are fine.)
One approach is a templated class that serves as the one implementation and type aliases of that class for your real types. This could look as follows:
namespace detail {
template<typename Alias>
struct Implementation {
//do everything once
};
}
using A = detail::Implementation<struct DummyA>;
using B = detail::Implementation<struct DummyB>;
using C = detail::Implementation<struct DummyC>;
As long as each uses a different type as the template argument, each will be a unique type with the same implementation, and the real class can be hidden away in something users shouldn't touch.
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