Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making identical C++ type aliases incompatible

Tags:

c++

c++11

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) ... 
like image 934
oz1cz Avatar asked Dec 23 '16 11:12

oz1cz


1 Answers

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.

like image 53
Christoph Diegelmann Avatar answered Sep 17 '22 03:09

Christoph Diegelmann