C++11 向量包含 2 个不同的子类,但不能同时进行



>假设我有一个基类Base,两个子类AB,后者本身有一个子类C

我想通过设计强制std::vector可以容纳任一类型的对象(包括C等子类(,但一次只能容纳一种类型——也就是说,我有一个As 的向量,或者一个Bs 和Cs 的向量。

是否可以在 C++11 中拥有这个(当然,我可以在向向量添加元素时强制执行此约束,但我想知道我是否可以通过巧妙的设计来防止这种情况(?如何构建类层次结构来获得此值?

提前感谢您的帮助!

R.

boost::variant< std::vector<A>, std::vector<boost::variant<B,C>> >描述了你的结构。

C++17 年,将boost::替换为std::. 两者非常相似,但不完全相同。

如果你不能使用boost,你基本上必须编写自己的variant

使用有点尴尬,但您的类型限制也是如此。 在 C++14 中使用自动 lambdas(我相信这会增强变体访问者的支持(变得更加容易。

在 C++14/17 中,您可能会执行以下操作(伪代码(

template<class F, class T, class=std::enable_if_t<!is_variant<T>{}>>
decltype(auto) visit( F&& f, T&& t ) {
return std::forward<F>(f)(std::forward<T>(t));
}
my_special_vec v;
visit( [&](auto&& v){
for (auto&& e:v) {
Base* b = visit( [&](auto&& e){
e.do_operation();
return std::addressof(e);
}, decltype(e)(e));
b->do_virtual_operation();
}
}, v );

它应该在向量包含的ABC中的任何一个上非虚拟地调用e.do_operation(),然后在实例上调用do_virtual_operation()作为Base

这是更简单的 C++14 版本。 C++11版本在函数对象和其他混乱中变得尴尬。

std::vector<T>只能容纳一种类型的对象:T。它永远不能保存派生对象,也不能在运行时更改类型。

通过使用间接寻址,可以单独分配对象,而是在向量中存储指向基类的指针。这允许向量指向派生对象,但不会阻止同时混合不同类型的对象。

您可以使用标记的联合实现您所描述的内容。C++11 标准库没有标记的联合类型(std::variant将在 C++17 中引入(,因此您需要自己实现它(或者您当然可以像往常一样使用第三方实现(。标记联合允许您列出可以存储的类型,并且一次有一个类型处于活动状态。所以你可以有一个变体std::vector<A>std::vector<A>std::vector<C>.

也就是说,您还没有描述为什么需要它,更好的设计可能是使用几个单独的向量。

最新更新