Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 定义具有最小大小的结构_C++_Struct - Fatal编程技术网

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)
就不小于某个值

动机:

我有一个vector
std::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的答案!