如何声明元素类型无默认构造函数的std::array?
报错原因
你对报错的判断是正确的:std::array属于聚合类型,默认初始化时会自动调用内部每个元素的默认构造函数;而你自定义的circular_buffer仅提供了带size_t参数的构造函数,编译器不会自动生成无参默认构造函数,因此触发了构造函数被隐式删除的报错。
解决方案
方案1:手动提供初始化列表(适配所有C++11及以上版本)
如果MAX_BUFFERS数值较小,你可以直接在std::array声明时传入构造好的circular_buffer实例:
constexpr size_t PER_BUF_SIZE = 1024; // 替换为你需要的每个环形缓冲区的容量 std::array<circular_buffer<TMyType>, MAX_BUFFERS> bufferArray = { circular_buffer<TMyType>(PER_BUF_SIZE), circular_buffer<TMyType>(PER_BUF_SIZE), // 重复上述构造语句MAX_BUFFERS次即可 };
方案2:通过模板辅助函数批量初始化(适配C++14及以上版本,推荐大尺寸MAX_BUFFERS使用)
如果MAX_BUFFERS数值较大,手动写重复的初始化项效率低,可以借助std::index_sequence批量生成初始化项:
首先定义辅助构造函数:
template <typename T, size_t ArraySize, typename... ConstructorArgs> std::array<circular_buffer<T>, ArraySize> make_circular_buffer_array(ConstructorArgs&&... args) { return []<std::size_t... IndexSeq>(std::index_sequence<IndexSeq...>) { // 折叠表达式批量构造MAX_BUFFERS个实例 return std::array<circular_buffer<T>, ArraySize>{ (static_cast<void>(IndexSeq), circular_buffer<T>(std::forward<ConstructorArgs>(args)...))... }; }(std::make_index_sequence<ArraySize>{}); }
之后直接调用辅助函数生成数组即可:
constexpr size_t PER_BUF_SIZE = 1024; // 替换为你需要的每个环形缓冲区的容量 auto bufferArray = make_circular_buffer_array<TMyType, MAX_BUFFERS>(PER_BUF_SIZE);
可选方案:给circular_buffer补充默认构造函数
如果你可以接受后续单独初始化每个环形缓冲区,也可以给circular_buffer补充无参默认构造:
template <class T> class circular_buffer { public: // 新增默认构造函数 circular_buffer() : buf(nullptr), max_size(0) {} circular_buffer(size_t size) : buf(std::unique_ptr<T[]>(new T[size])), max_size(size) {} // 剩余类定义不变 private: std::unique_ptr<T[]> buf; size_t max_size; };
该方案下你原来的bufferArray声明可以直接编译通过,但需要额外补充resize之类的接口,后续逐个设置每个缓冲区的容量,灵活度更低,非特殊场景不推荐。
内容的提问来源于stack exchange,提问作者DavidA
相关产品推荐
相关产品推荐

