具有不同包含类型的 STL 容器
STL container with different contained types?
假设我有不同类型的结构组件。也许我有TransformComponent
和RigidBodyComponent
现在,这就是问题所在:我想要一个类似std::map
的东西,您可以在其中将组件类型和 id 映射到组件。ID 是将组件链接在一起的原因。我应该为此使用哪种容器?我不能使用std::map<std::typeindex, std::map<id_t, T>>
,因为类型T
取决于您用于索引第一张地图的类型索引。
您的用例听起来像是多态性的典型用法。您应该知道,任何在单个容器中存储"非同质"类型的尝试都会带来多态性的性能损失。至于您是使用 C++ 提供的"开箱即用"多态性还是选择自定义解决方案 - 这完全取决于您。
顺便说一句,引用有关该问题的评论中的一个问题:
这是一个非常好的问题,因为假设您可以拥有这样的容器。你会用它做什么?能 您展示了一些预期的使用示例?
揭示您的特定使用场景将允许其他人更详细地回答您的问题,因为现在听起来您并不真正知道自己在做什么或需要做什么。因此,如果您需要进一步的指导,您应该真正澄清并建立您的问题。
如果您需要使用包含不同类型的容器,请查看一些 BOOST 库:
Any:用于不同值类型的单个值的安全通用容器。(http://www.boost.org/doc/libs/1_54_0/doc/html/any.html(
变体:安全、通用、基于堆栈的区分联合容器 (http://www.boost.org/doc/libs/1_54_0/doc/html/variant.html(
如果类型列表已明确定义且未更改,请使用变体。
因此,您的代码可能如下所示:
typedef boost::variant<TransformComponent, RigidBodyComponent> my_struct;
std::map<std::typeindex, std::map<id_t, my_struct> > cont;
...
std::typeindex index = std::type_index(typeid(TransformComponent));
std::map<id_t, my_struct> & m = cont[index];
id_t id = ...;
TransformComponent & component = boost::get<TransformComponent>(m[id]);
这段代码非常丑陋,所以考虑改变架构。也许使用boost::any或boost::variant会更简单。
附言如果您编写模板代码,那么最好查看 boost::mpl。
如果您不介意编写一个使用 ye olde C hacking 的自定义容器,则可以解决此问题。
我在这里给你写了一个例子:
#include <iostream>
using namespace std;
struct ent
{
int myInt;
};
struct floats
{
float float1;
float float2;
};
struct container
{
bool isTypeFloats;
union
{
ent myEnt;
floats myFloats;
};
};
void main( void )
{
ent a = { 13 };
floats b = { 1.0f, 2.0f };
container c;
container d;
cout << b.float1 << " " << b.float2 << endl;
c.isTypeFloats = false;
c.myEnt = a;
d.isTypeFloats = true;
d.myFloats = b;
//correct accessor
if( c.isTypeFloats )
{
cout << c.myFloats.float1 << " " << c.myFloats.float2 << endl;
}
else
{
cout << c.myEnt.myInt << endl;
}
if( d.isTypeFloats )
{
cout << d.myFloats.float1 << " " << d.myFloats.float2 << endl;
}
else
{
cout << d.myEnt.myInt << endl;
}
}
要将这些结构放在容器中,您只需执行以下操作:std::vector< container >
关于这一点,您应该了解几件事:
- 联合为最大的类型分配空间。所以在我的示例中,如果一个 int 需要 4 个字节,一个浮点数需要 4 个字节,那么即使我只存储一个
ent
它也会为floats
分配空间,所以我每次存储一个ent
时都会浪费 4 个字节。根据应用程序的用途和要存储的类型的大小,这可能可以忽略不计。 - 如果您存储的类型在大小上存在显着差异,那么您可以按照C++真正处理引擎盖下联合的方式进行此操作。那就是使用
void*
.所以你会这样做:std::vector< void* > myVec
你会像这样插入:myVec.push_back( &x )
x
是你的类型,例如我们示例中的ent
。但是读出来,你必须知道你指的是什么,所以你必须知道做这样的事情:cout << ( ( ent* )myVec[0] )->myInt << endl;
因为除非你有一些预定义的写作模式,否则你可能不知道它是什么类型,所以你可能最终只想使用这样的容器结构:
结构容器2{ 布尔值是类型浮点数; 无效*我的联盟;}
boost::any 或 boost::any_cast 怎么样?
http://www.boost.org/doc/libs/1_54_0/doc/html/any.html
- 在STL容器中使用模板类
- 检查函数返回类型是否与STL容器类型值相同
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 对象 C++ 向量的 STL 容器
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- 在 STL 容器的 STL 容器上调用 clear
- "迭代器"和"const_iterator"不是 STL 容器的必需成员?
- 删除包含包含动态对象的 STL 容器的智能指针
- C++:在子类中扩展静态 STL 容器/映射成员?
- ostream 运算符<< 为获取 STL 容器而过载,传递 std::string 会破坏它?
- 没有 STL 容器的迭代器
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 接受任何 STL 容器的函数
- C++ STL 容器中优先级搜索的优雅方法
- 我们如何打印出C++ STL 容器的value_type?
- 获取嵌套 stl 容器的大小(以字节为单位)
- 如何在C++中重新实现包含指针的 STL 容器的类的迭代器
- 迭代器和 STL 容器的关系
- 如何用索引增量generate_n填充STL容器