首页 > 解决方案 > 如何结合切片、模板和非派生类?

问题描述

我想要一个可以摄取对象的容器,并将其不同部分存储到不同的内部容器中。

像这样的东西:

// Pseudo-code

template<typename A, typename B, typename C>
class Container {
   std::vector<B> vb;
   std::vector<C> vc;
public:
   void push_back(const A &a) {
      vb.push_back(a);
      vc.push_back(a);
   }
};

class AA {
   int a;
   std::string s;
};

class BB {
   int a;
};

class CC {
   std::string s;
};

Container<AA, BB, CC> cont;

AA aa;
cont.push_back(aa);

我希望 objectvb获得 A 和 B 类(切片)之间的共同点,对于 object 也是如此vc

理想情况下,AA、BB 和 CC 类不应处于层次关系中。我希望编译器能够按成员的类型匹配成员。

我更喜欢性能损失较小的解决方案。

标签: c++templatesderived-classobject-slicing

解决方案


您的伪代码容器已经在AA继承BB和的情况下工作CC,因为切片允许从派生到基的隐式转换。但是,您的实施不限于这种情况。所需要的只是AA隐式转换为BBCC。继承就足够了,但不是必需的。

您可以通过定义转换运算符使一个类可转换为其他类:

struct AA {
   operator BB() const { return {a}; }
   operator CC() const { return {s}; }
   int a;
   std::string s;
};

或者,您可以添加一个转换构造函数BB和/或CC如果您希望依赖项采用另一种方式:

struct BB {
   BB(const AA& aa) : a(aa.a) {}
   int a;
};

但是请注意,缩小诸如此类的隐式转换可能会导致某些错误被忽视。


推荐阅读