代码之家  ›  专栏  ›  技术社区  ›  Treebeard

std::数组与连续内存的c样式数组

  •  0
  • Treebeard  · 技术社区  · 7 年前

    这是一个只为了兴趣的实验…

    我正在尝试创建一个容器,它在一个连续的内存块中保存固定数量的字节(如头)和动态数据块(如正文)。在传统的c编程中 char[0] 作为最后一个实例变量,我会过度分配 sizeof(struct) + data_length .

    这工作在C++中,但是我想要更好的东西。所以我的问题是 std::array 从一个指针开始,或者它可以与本机c样式数组一样使用吗?

    下面是一些示例代码…

    struct pkg_base
    {
        virtual std::size_t get_body_size() = 0;
        virtual void *get_body_ptr() = 0;
    };
    
    template<typename _T, std::size_t _N>
    struct pkg
        : public pkg_base
    {
        std::uint16_t a;
        std::uint16_t b;
        std::uint16_t c;
    
        std::array<_T, _N> body{};
    
        std::size_t get_body_size() override
        {
            return ( body.size() );
        }
    
        virtual void *get_body_ptr() override
        {
            return ( body.data() );
        }
    };
    
    void _test_package()
    {
        auto vec = std::vector<std::unique_ptr<pkg_base>>{};
        vec.push_back(std::make_unique<pkg<char, 1024>>());
        vec.push_back(std::make_unique<pkg<float, 1024>>());
        vec.push_back( std::make_unique<pkg<std::string, 1024>>() );
    
        auto const size = vec.front()->get_body_size();
        auto const *ptr = static_cast<char *>( vec.front()->get_body_ptr() );
    }
    
    4 回复  |  直到 7 年前
        1
  •  1
  •   SergeyA    7 年前

    作为参考,您所指的技术称为 flexible array member 而且,不幸的是,它在C++中不支持作为核心特征或标准库函数。我觉得这令人失望。

    std::array 是一个经过修饰的c样式数组(有一些成员允许它用作stl容器,如迭代、大小调整、类型内省等)。

    我知道实现类似于灵活数组成员的功能的唯一方法是创建一个 std::vector<char> ,大小设置为 sizeof(header) + <extra bytes for payload> ,以及 placement new 标题在 vector.data() .您可以将所有这些打包到helper类中,以节省您在多个场景中的一些输入。

        2
  •  3
  •   Useless    7 年前

    所以我的问题是std::数组是以指针开头的,还是可以用与本机c样式数组相同的方式使用它?

    the documentation

    此容器是一个聚合类型,其语义与将C样式数组t[n]作为其唯一非静态数据成员的结构相同。

    所以里面没有其他数据成员,只有 T[N] 你想要的阵列。

    您可以使用 sizeof 或者看看密码。

    作为旁白,名字以 _[A-Z] 是为实现保留的,因此您可能不应该调用模板类型参数 _T _N 是的。

        3
  •  2
  •   Jack    7 年前

    一个 std::array 不包含指向其他地方数据的任何指针,a std::数组 直接在内部保存数据,里面没有任何动态的东西。

    它被设计为提供类似于标准数组的语义,但具有标准stl容器的一些特性。

    它是一个聚合类,主要实现为

    namespace std
    {
      template<typename T, size_t S>
      class array
      {
        T __elems_[S];
      }
    }
    

    你有 array.data() 它已经返回了一个c数组,所以我没有得到你的要求。

        4
  •  0
  •   Red.Wave P.W    7 年前

    我可以建议你把删除字体作为解决问题的一般方法。在现代C++中,有一种倾向是避免直接处理原始指针,除非不可避免:

    struct common_part{
        //declare common data and ctor
    protected:
        virtual elem* end(){return begin()+size();};
        virtual elem *begin()=0 ;
        virtual ~common_part()=default;
        virtual std::size_t size()=0;
    };
    
    template<std::size_t N>
    struct instance_type:
        common_part{
    protected:
        void elem* begin() override{return arr;};
        void elem* end() override{return arr+N;};
        void std::size_t size() override{return N;};
    private:
        elem arr[N];
    };
    
    std::unique_ptr<common_part> ptr {new instance_type<N>{}};