C++ 定义具有最小大小的结构
我想定义一个结构,例如C++ 定义具有最小大小的结构,c++,struct,C++,Struct,我想定义一个结构,例如type,这样sizeof(type)就不小于某个值 动机: 我有一个vectorstd::vector,我将从中删除一些元素。此外,我还将一些元素的索引保存到其他位置,因此我只想将其标记为未使用,并在将来重用它。这使我将下一个可用位置保存为已擦除位置的列表。因此,sizeof(type)应不小于sizeof(size\u t),并且type也应正确对齐 可能的解决方案: boost::variant 在我看来,这有两个问题。如果我使用boost::get,性能将显著降低。
type
,这样sizeof(type)
就不小于某个值
动机:
我有一个vectorstd::vector
,我将从中删除一些元素。此外,我还将一些元素的索引保存到其他位置,因此我只想将其标记为未使用,并在将来重用它。这使我将下一个可用位置保存为已擦除位置的列表。因此,sizeof(type)
应不小于sizeof(size\u t)
,并且type
也应正确对齐
可能的解决方案:
boost::variant
在我看来,这有两个问题。如果我使用boost::get
,性能将显著降低。如果我使用boost::apply_visitor
,语法会很奇怪,性能也会随着我的配置文件而降低union{type t;size\t s;}
这当然有效,但有两个缺点。首先,引用类型
的成员的语法将更加混乱。其次,我必须为这个联合定义构造函数、复制构造函数等char[sizeof(size\u t)-sizeof(type)]扩展type
这几乎满足了我的要求。然而,这种零长度数组的风险是不受C++标准支持的,可能是错误的对齐。
type
作为size\u t
,因此我只想确保在需要时可以使用reinterpret\u cast
补充
在阅读了这些评论之后,我认为解决我的问题的最好办法应该是boost::variant
。但我仍然想知道是否有一种方法可以将解决方案2和3的优点结合起来,即
a。我可以访问类型的成员,无需更改
b。获得重新解释转换工作的保证。您可以通过以下方式缓解对解决方案3的担忧:
struct data
{
// ...
};
template<class T, bool> class pad_;
template<class T> class pad_<T, true> { char dummy[sizeof(T) - sizeof(data)]; };
template<class T> class pad_<T, false> {};
template<class T> using pad = pad_<T, (sizeof(T) > sizeof(data))>;
class type : public data, pad<size_t>
{
// ...
};
struct数据
{
// ...
};
模板类pad;
模板类pad{char dummy[sizeof(T)-sizeof(data)];};
模板类pad{};
模板使用pad=pad_u;sizeof(data))>;
类类型:公共数据,pad
{
// ...
};
此代码:
- 假设当
sizeof(data)>=sizeof(size\t)
- 没有零长度数组的风险吗
尽管这是一个有趣的问题,但设计本身还是有问题的
插入新元素时,在增长向量之前,首先考虑标记为未使用的项。这意味着项目的相对顺序是不可预测的。如果这是可以接受的,您可以使用(智能)指针向量
通常,从中间删除项时,向量效率很低。因为顺序无关紧要,所以可以将要删除的元素与最后一个元素交换,然后弹出最后一个元素
所有元件尺寸相同;使用池分配它们可能比使用系统分配器更快
一个池基本上是以大块的形式分配内存,并根据请求分发小块的内存。池通常将空闲列表存储在尚未分配的块中,以跟踪可用内存(与问题中描述的想法相同)。有一些很好的实现(来自Boost和其他来源)
关于原始设计,枚举向量中的元素很麻烦,因为实元素与“孔”混合,逻辑将通过额外的检查变得模糊
在最初的设计背后可能有一些被出卖的理由;不幸的是@user1535111没有透露细节。这个问题问得很好+1.但在我看来,问题的根源在于保存索引以备将来使用。我认为你应该考虑一些不涉及这种骗局的替代方案,向量中的某些元素是向量中下一个有效的索引。@bolov我同意你的看法。我在vector和saved type*中使用了unique_ptr。但我更喜欢直接访问的类型。(它不是用于生产)事实上,我认为boost::variant可能是我的最终解决方案,但我期待着更好的解决方案。为什么你认为boost::variant会带来性能成本?@RichardHodges,我不是在想象。是的,我已经证实了。我认为这回避了一个问题,“为什么不只进行内存分配?”Stl容器已经有了自定义分配器的概念,以防new/delete不足以满足我们的需要。这看起来很棒。最后一个问题是,如果用作大小,是否存在对齐问题?对于对齐,您应该在类型定义(C++11)中添加一个说明符,或者尝试使用。所有这些都很棘手,我不确定是否值得麻烦。完全正确!这个设计有问题!我将回到指针。然而,这并不能回答所问的问题,所以我选择了manlio的答案!