I use std::vector<int>
for two different kinds of information. I want to be sure that I don't accidentally mix the two uses.
In short, I want something like this piece of code to fail:
#include <vector> using A = std::vector<int>; using B = std::vector<int>; void fa(const A&); void fb(const B&); void fun() { A ax; B bx; fa(bx); fb(ax); }
This code compiles, even though fa
expects an argument of type A
. Obviously, A
and B
are identical.
What is the simplest way to make this code compile correctly:
fa(ax); fb(bx);
and make this code fail:
fa(bx); fb(ax);
Of course, I can wrap std::vector<int>
within another class, but then I'll need to rewrite its interface. Alternatively, I could inherit from std::vector<int>
, but this is frequently discouraged.
In short, I need two incompatible versions of std::vector<int>
.
EDIT
It has been suggested that Strong typedefs can solve this problem. This is only partially true. If I use BOOST_STRONG_TYPEDEF(std::vector<int>, A)
, I need to add some annoying casts. For example, instead of
A ax{1,3,5};
I need to use
A ax{std::vector<int>{1,3,5}};
And instead of
for (auto x : ax) ...
I need to use
for (auto x : (std::vector<int>)ax) ...
I think what you want is still best achieved with:
struct A : public std::vector<int>{ using vector::vector; }; struct B : public std::vector<int>{ using vector::vector; };
It does exactly what you want. There's no reason to come up with some ugly hackery just to avoid a clean statement. The main reason I see that such subtyping is not favored is that the same things should behave like they are the same and can be used interchangeably. But that is exactly what you want to suppress, and therefore subtyping it makes exactly the statement that you want: they have the same interface but they shouldn't be used the same because they aren't the same.
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