You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写含删除默认构造函数类数组的constexpr构造函数

解决删除默认构造函数后数组成员的初始化问题

你的分析完全正确:当B的构造函数未使用初始化列表初始化数组arr_时,编译器会先尝试默认初始化数组的每个元素,但A的默认构造函数已被删除,因此触发编译错误。构造函数体里的赋值操作是在初始化完成后执行的,无法绕过这一步。

以下是两种可行的解决方案,均能保持代码的constexpr特性:

方案1:利用索引序列初始化原生数组

通过模板构造函数配合std::index_sequence,在初始化列表中直接调用A的带参构造函数逐个初始化数组元素:

#include <utility> // 引入std::index_sequence相关工具

constexpr int data[] = {1,2,3,4,5};
constexpr size_t N = sizeof(data)/sizeof(int);

struct A { 
    A() = delete;
    constexpr A(int a): a_(a) {}
private:
    int a_ = 0;
};

struct B{
private:
    // 辅助模板构造函数,接收索引序列展开初始化
    template<size_t... Is>
    constexpr B(std::index_sequence<Is...>) : arr_{A(data[Is])...} {}

public:
    // 对外构造函数,生成对应长度的索引序列
    constexpr B() : B(std::make_index_sequence<N>{}) {}
private:
    A arr_[N];
};

方案2:改用std::array容器

如果允许替换原生数组为std::array,实现方式类似,代码可读性更好:

#include <utility>
#include <array>

constexpr int data[] = {1,2,3,4,5};
constexpr size_t N = sizeof(data)/sizeof(int);

struct A { 
    A() = delete;
    constexpr A(int a): a_(a) {}
private:
    int a_ = 0;
};

struct B{
private:
    template<size_t... Is>
    constexpr B(std::index_sequence<Is...>) : arr_{{A(data[Is])...}} {}

public:
    constexpr B() : B(std::make_index_sequence<N>{}) {}
private:
    std::array<A, N> arr_;
};

核心原理:两种方案都是通过编译期的索引序列展开,直接在初始化列表中完成每个A对象的带参构造,完全跳过了默认构造的步骤,既满足constexpr要求,又规避了默认构造函数被删除的问题。

内容的提问来源于stack exchange,提问作者u0804138

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 02:17:09