是否有可以存储不同类型物品的容器?

时间:2015-02-21 03:41:34

标签: c++11 tuples variadic-templates

存储相同类型的项目是微不足道的,但我需要一个可以存储不同类型项目的容器。

这是一个显示我想做的事情的例子:

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[]

3 个答案:

答案 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"