如何在C ++容器中存储不同types的对象?

是否有一个C + +容器,我可以使用或build立,可以包含,比如intstringdoubletypes? 我面临的问题是,每当我尝试填充,比如说,一个地图,向量或列表,如下所示:

 int x; string y; double z; 

我受限于格式:

 list<int> mycountainer; vector<string> mycontainer; 

迫使我的mycontainer只包含一种types。

在任何人build议使用generics之前,由于C ++自带的标准vectorlist容器已经是通用的 ,它们可能是任何types的容器,但不能包含多种types。

我想避免使用Boost,如果可能的话 – 如果有一个简单的方法,我可以自己编写代码。

嘿家伙,非常感谢您的build议 – 我应该解释我将如何使用这个容器,但是这是一个复杂的因此上面的(大)简化。 我认为这里最好的select是使用Boost。 再次感谢。

您可以使用(或重新实现) boost::any ,并将boost::any实例存储在容器中。 这将是最安全的,因为在一般情况下, boost::any可能处理了解决这类问题所涉及的许多边界情况和复杂性。

如果你想做一些快速和肮脏的事情,可以创build一个结构或者包含所有潜在types的成员的联合,以及对象中的哪个types为“活动”的枚举或其他指示符。 对于工会要特别小心,因为他们有一些有趣的属性(例如,如果你阅读了错误的联合成员,就会调用未定义的行为,一次只有一个成员可以是“活跃”的,最近被写入的成员)。

不过,我很好奇你在做什么,你需要这样的构造。

那么,第一个问题是: 为什么你认为你需要在同一个容器中存储不同的,完全不相关的types的对象? 这对我来说似乎很腥。

如果我有这个需要,我会研究boost::variantboost::any

你想要什么被称为“hetrogenious容器”。 C ++在技术上并没有在STL中支持它们,但Boost的确如此。

鉴于此,我想你会在这个问题上find你的答案: 你怎么做一个异构boostmap

您可以使用结构,或类或std :: pair。

[编辑]

对于类和结构:

 struct XYZ { int x; string y; double z; }; std::vector<XYZ> container; XYZ el; el.x = 10; el.y = "asd"; el.z = 1.123; container.push_back(el); 

对于std :: pair:

 #include <pair> typedef std::pair<int, std::pair<string, double> > XYZ; std::vector<XYZ> container; container.push_back(std::make_pair(10, std::make_pair("asd", 1111.222))); 

你可以使用一个包含所有三个结构的结构。

 struct Data { int intVal; std::string stringVal; double doubleVal; }; 

然后,您可以声明list mycontainer<Data>并使用适当的值,只要您知道值types是什么。 如果不是,则在结构中添加一个附加字段,告诉您正在使用三种数据types中的哪一种。

 struct Data { enum DATATYPE { DT_INT, DT_STRING, DT_DOUBLE } type; int intVal; std::string stringVal; double doubleVal; }; 

如果你担心内存使用,你可能可以使用联合,但我倾向于避免使用它们。 虽然我可能是不必要的偏执狂。

如果您需要存储的项目数量有限,请将其放入课程或结构中。

如果没有限制,你需要在这个容器中存储的东西,然后看看不同的方式做事情,因为唯一的方法是将它们存储为一个对象,然后将它们转换为它们自己的types需要访问它们。

但是,如果任何项目可能位于容器中,则无法知道容器中的特定types项目,因此将无法投射它们。

如果C ++包含reflection,可能会有一种方法来做到这一点,但C ++没有reflection。

最简单的方法当然是定义一个结构或类,它包含你想要存储的每个types的成员。 乔希的回答暗示了Boost.Any ,这将持有几乎任何东西 。 如果你想限制只有intdoublestd::stringtypes的值,那么更好的select是Boost.Variant 。

如果你根本不想使用Boost,那么我build议你把你的问题解决掉,然后使用它。 “这里没有发明”是一个自我毁灭的政策。 但是如果你不能使用Boost,那么你可以写你自己的变体类。 Andrei Alexandrescu在几年前写了一个由三部分组成的系列文章( 第1部分 , 第2 部分 , 第3部分 ),其devise灵感来自于Boost的使用。