使相同的C ++types别名不兼容

我使用两种不同types的信息std::vector<int> 。 我想确保我不会不小心混合这两种用途。

总之,我想要这样的一段代码失败:

 #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); } 

即使fa预期typesA的参数,此代码编译。 显然, AB是相同的。

什么是使这个代码正确编译的最简单的方法:

 fa(ax); fb(bx); 

并使此代码失败:

 fa(bx); fb(ax); 

当然,我可以在另一个类中包装std::vector<int> ,但是我需要重写它的接口。 另外,我可以inheritancestd::vector<int> ,但是这经常是不鼓励的。

总之,我需要两个不兼容的std::vector<int>

编辑

有人build议Strong typedefs可以解决这个问题。 这只是部分正确的。 如果我使用BOOST_STRONG_TYPEDEF(std::vector<int>, A) ,我需要添加一些烦人的强制转换。 例如,而不是

 A ax{1,3,5}; 

我需要使用

 A ax{std::vector<int>{1,3,5}}; 

而不是

 for (auto x : ax) ... 

我需要使用

 for (auto x : (std::vector<int>)ax) ... 

我认为你想要什么仍然是最好的实现:

 struct A : public std::vector<int>{ using vector::vector; }; struct B : public std::vector<int>{ using vector::vector; }; 

它正是你想要的。 没有理由想出一些丑陋的黑客来避免干净的声明。 我看到这种分类不受欢迎的主要原因是,同样的事情应该像他们是相同的,可以交替使用。 但是,这正是你想要压制的东西,因此子types正是你想要的语句:它们具有相同的接口,但不应该因为它们不相同而使用相同的接口。

无论如何,这是一个原始痴迷的情况。 要么int确实代表某事物, vector是某物的集合,要么vector<int> s代表某物。

在这两种情况下,都应该通过将原语包装成更有意义的东西来解决。 例如:

 class column { int id; /*...*/ }; class row { int id; /*...*/ }; 

std::vector<row>std::vector<column>不能互换。

当然,如果vector<int>是真的意味着别的东西,那么相同的想法可以应用于vector<int>而不是int

另外,我可以从std :: vectorinheritance,但是这经常被劝阻。

国际海事组织,这取决于情况。 一般来说可能是一个好的解决scheme

 #include <vector> class VectorA : public std::vector<int> { public: VectorA() = default; ~VectorA() = default; VectorA(const VectorA&) = default; VectorA(VectorA&&) = default; VectorA& operator=(const VectorA&) = default; VectorA& operator=(VectorA&&) = default; }; class VectorB : public std::vector<int> { public: VectorB() = default; ~VectorB() = default; VectorB(const VectorB&) = default; VectorB(VectorB&&) = default; VectorB& operator=(const VectorB&) = default; VectorB& operator=(VectorB&&) = default; }; 

您仍然可以使用VectorAVectorB作为法线vector,但不能在它们之间切换。

 void acceptA(const VectorA& v) { // do something } void acceptB(const VectorB& v) { // do something } template<typename T> void acceptVector(const std::vector<T>& v) { // do something } int main(int argc, char *argv[]) { VectorA va; VectorB vb; acceptA(va); // you can only pass VectorA acceptB(vb); // same here for VectorB acceptVector(va); // any vector acceptVector(vb); return 0; } 

这就是为什么你可以用C ++进行面向对象的编程,以及重用库types的基于对象的编程。

使A和B类模拟您的域中的行为。 如果这两种行为都是以字段为向量的字段来实现,那么这并不重要; 只要你不打破封装,不同载体上的所有操作都将在其范围内,不会发生混淆。

 #include <vector> class A { std::vector<int> cake_orders_; public: void f() ; // can only do something to do with cake }; class B { std::vector<int> meal_worm_lengths_; public: void f() ; // can only do something to do with worms }; void fun() { A ax; B bx; af(); // has to be the right thing bf(); }