存储相同类型的项目是微不足道的,但我需要一个可以存储不同类型项目的容器。
这是一个显示我想做的事情的例子:
Class C
{
};
C c1;
C c2;
C c3;
std::tuple<C> tup1(c1);
std::tuple<C, C> tup2(c1, c2);
std::tuple<C, C, C> tup3(c1, c2, c3);
container_type container(tup1, tup2, tup3);
是否有任何容器以这种方式工作?如果没有,有没有办法创建一个?
我希望快速随机访问重载operator[]
。
答案 0 :(得分:1)
它无效。您正在将编译时多态(元素类型和元组计数)与运行时多态混合(您希望在容器中存储不同大小的元组)。
在您的示例中,container[0].get<2>
应该返回什么?保证元组是编译时检查的,因此没有运行时信息来检查2是否是有效索引,因此抛出异常或返回默认构造对象不会仅仅因为使用元组而发生。
在您的示例中,无论如何,您将复制或移动元组(将它们插入容器时),这意味着您需要复制或移动所有元素。您可以不将元组元素复制到(新)元组中,而是将元组元素复制到std :: vectors中。函数tuple_to_vector需要一些模板魔术来有效地实现,我现在没有时间起草。
如果您可以更改API以返回std :: arrays而不是std :: tuples(实际上保证了同类型和连续存储,并提供运行时索引),转换为vector函数将非常简单写。
答案 1 :(得分:1)
运行时多态性需要间接和多态类型。根据其性质,什么元组不是。
你可以做的是让你的对象成为继承层次结构的一部分,并存储在动态分配对象的容器(智能)指针中(动态分配是必要的,因为它们是不同类型的对象,它们也有不同的大小),或者将您的对象包装到一个类(例如boost::any
)中,该类执行“类型取消”,主要是通过内部执行所需的间接方式。)
在任何情况下,容器接口在执行此操作时都将访问指针或包装器。您可以在运行时检查每个引用对象的实际类型,然后再访问其自己的特定功能,或者仅依赖于所有引用对象的共同虚拟功能。
答案 2 :(得分:0)
类似的东西:
auto tuple = std::make_tuple(1, "foo", 3.12);
auto foo = std::get<1>(tuple); // will be a string containing "foo"