Is there a container that can store items of different types?

ε祈祈猫儿з 提交于 2019-12-13 04:26:09

问题


Storing items of the same type is trivial, but I need a container that can store items of different types.

Here's an example showing what I'd like to do:

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

Is there any container that works in this way? If not, is there a way to create one?

I'd like something that overloads operator[] for fast random access.


回答1:


It won't work. You are mixing compile-time polymorphism (the element types and count of a tuple) with run-time polymorphism (you want to store differently sized tuples in a container).

In your example, what should container[0].get<2> return? Tuples are guaranteed to be compile-time checked, so there is no runtime information to check whether 2 is a valid index, so throwing an exception or returning a default constructed object can't happen just from using the tuple.

In your example, you are going to copy or move the tuple (when inserting them into the container) anyway, which means you need to copy or move all the elements. You could instead of copying the tuples elements into (new) tuples copy the tuple elements into std::vectors. The function tuple_to_vector would need some template magic to implement efficiently, which I don't have the time to draft up right now.

If you can change the API to return std::arrays instead of std::tuples (which actually guarantee homogenous type and contiguous storage, and provide run-time indexing), a convert-to-vector function would be quite trivial to write.




回答2:


Run-time polymorphism requires indirection and polymorphic types. What tuples, by their nature, aren't.

What you can do is make your objects part of an inheritance hierarchy, and store in the container (smart)pointers to dynamically allocated objects (dynamic allocation is necessary, since being objects of different types they also have different sizes), or wrap your objects into a class (like boost::any, for example) that does "type cancellation", essentially by doing internally the indirection required).

In any case, the container interface, when doing this, will access the pointers or the wrappers. It's up to you to check at runtime the actual type of each referred object before accessing its own specific functions, or to rely only to the virtual function that are common to all.




回答3:


Something like:

auto tuple = std::make_tuple(1, "foo", 3.12);
auto foo = std::get<1>(tuple); // will be a string containing "foo"

?



来源:https://stackoverflow.com/questions/28641836/is-there-a-container-that-can-store-items-of-different-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!