std::array与C样式数组用于连续内存
std::array vs C-Style array for contiguous memory
这只是一个有趣的实验。。。
我正在尝试制作一个容器,它将固定数量的字节(例如标头(和动态数据块(例如正文(全部保存在一个连续的内存块中。在传统的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() );
}
所以我的问题是std::数组是以指针开头的,还是可以像本地C风格数组一样使用?
来自文档
此容器是一个聚合类型,其语义与将C样式数组T[N]作为其唯一非静态数据成员的结构相同。
所以里面没有其他数据成员,只有您想要的T[N]
数组。
您可以使用sizeof
或查看代码来轻松地确认这一点。
顺便说一句,以_[A-Z]
开头的名称是为实现保留的,所以您可能不应该调用模板类型参数_T
和_N
。
std::array
不包含任何指向其他地方的数据的指针,std::array
直接在内部保存数据,其中没有任何动态内容。
它被设计为提供类似于标准数组的语义,但具有标准STL容器的一些特性。
它是一个聚合类,主要实现为
namespace std
{
template<typename T, size_t S>
class array
{
T __elems_[S];
}
}
您有array.data()
,它已经返回了一个C数组,所以我不了解您的要求。
作为参考,您所指的技术称为flexible array member
,不幸的是,它在C++中不支持作为核心功能或标准库函数。我觉得这很令人失望。
std::array
是一个经过修饰的C风格数组(有一些成员允许它用作STL容器,如迭代、大小调整、类型内省等(。
我所知道的实现类似于灵活阵列成员的功能的唯一方法是创建一个std::vector<char>
,其大小设置为sizeof(header) + <extra bytes for payload>
,而不是vector.data()
中的placement new
标头。您可以将所有这些封装在一个helper类中,为自己节省一些针对多个场景的键入。
我可以建议将类型擦除作为问题的通用解决方案。在现代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>{}};
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 重载操作程序时出错>>用于类中的字符串 memebr
- 模板元程序查找相似的连续类型名称
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- C++将shared_ptr用于连续分配的内存
- std::array与C样式数组用于连续内存
- 用于查找连续子数组的最大总和的代码使测试用例失败
- 用于 c++ 媒体流的 N-API 连续回调
- C++用于将函数应用于连续元素的算法
- 用于搜索位阵列以查找连续设置/清除位的快速代码