Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating several mutually incompatible numerical types [duplicate]

Tags:

c++

c++11

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.)

like image 942
Jukka Suomela Avatar asked Dec 26 '22 22:12

Jukka Suomela


1 Answers

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.

like image 91
chris Avatar answered May 14 '23 19:05

chris