是否可以在 std::array 内创建 std::array 的 constexpr 值?

问题描述 投票:0回答:2

我正在优化一些设置代码。这是一个大型预定义值数组,分为三个嵌套结构。它被定义为

struct PerId
{
    const Id m_Id;
    const uint32_t m_Flags;
};

struct PerSeverity
{
    const Severity m_Severity;
    const std::vector<PerId> m_PerId;
};

struct PerTask
{
    const Task m_Task;
    const std::vector<PerSeverity> m_PerSeverity;
};
static const std::array rawSettingsPerTask
{
    PerTask{
        eTASK1,
        {{Severity::Critical, {{Violated, 0x22}, {Expired, 0x33}}},
         {Severity::Error, {{CantBeExecuted, 0x44}}}},
    },
    PerTask{
            eTASK2,{....}
    },
};

我想在编译时定义此设置。我将 constexpr 构造函数创建为 struct 并从 std::vector 移至 std::array,现在由于模板参数不同,我遇到了编译问题:

template<std::size_t N>
struct PerSeverity
{
    constexpr PerSeverity(Severity severity, const std::array<PerId, N>& perId)
        : m_Severity(severity)
        , m_PerId(perId)
    {}

    const Severity m_Severity;
    const std::array<PerId, N> m_PerId;
};

template<std::size_t N, size_t M>
struct PerTask
{
    constexpr PerTask(enTaskID component, const std::array<PerSeverity<M>, N>& perSeverity)
        : m_Component(component)
        , m_PerSeverity(perSeverity)
    {}

    const enTaskID m_Component;
    const std::array<PerSeverity<M>, N> m_PerSeverity;
};
constexpr std::array rawSettingsPerComponent
{
    PerComponent<1,2>{
        eTASK1, { PerSeverity<2>{Critical, { PerId{Violated, 0x22},
                                             PerId{Expired, 0x33}}}}
    },
    PerComponent<2,2>{
        eTASK2 , { PerSeverity<2>{ Critical, { PerId{Violated, 0x11},
                                               PerId{Expired, 0x22}}},
                   PerSeverity<1>{ Informational, { PerId{Violated, 0x44}}}}
    }
}

那么这可能吗?可能我需要一些技巧,但我找不到类似的东西。

完整示例此处

c++ c++17
2个回答
1
投票

您不能将

PerSeverity<1>
放入
PerTask<2,2>
中,也不能将
PerTask<1,2>
PerTask<2,2>
混合在
std::array
中。

您可以使用

std::array
代替
std::tuple
,但这会让 rawSettingsPerComponent 的消费者
更难。

template<std::size_t N> struct PerSeverity { constexpr PerSeverity(Severity severity, const std::array<PerId, N>& perId) : m_Severity(severity) , m_PerId(perId) {} const Severity m_Severity; const std::array<PerId, N> m_PerId; }; template<typename... Severities> struct PerTask { constexpr PerTask(enTaskID component, const std::tuple<Severities...>& perSeverity) : m_Component(component) , m_PerSeverity(perSeverity) {} const enTaskID m_Component; const std::tuple<Severities...> m_PerSeverity; }; constexpr std::tuple rawSettingsPerComponent { PerTask{ eTASK1, std::tuple{ PerSeverity<2>{Critical, { PerId{Violated, 0x22}, PerId{Expired, 0x33}}}} }, PerTask{ eTASK2 , std::tuple{ PerSeverity<2>{ Critical, { PerId{Violated, 0x11}, PerId{Expired, 0x22}}}, PerSeverity<1>{ Informational, { PerId{Violated, 0x44}}}} } };
    

0
投票
不,不是(有点)。对于数组,您需要数组的固定大小(=元素数量)

元素的固定大小。

这个(以及其他一些属性)是由元素的

type 强制执行的。理论上,同一个数组中可以存储不同类型但相同大小的元素。要在 C++ 中做到这一点,需要更多代码。

例如,您可以尝试使用

std::variant

 作为元素类型。它保证相同的大小(使用变体支持的所有类型的最大所需大小 - 
可能浪费大量内存并且所有元素的类型相同。

个人注释,如果您允许: 我强烈建议在实现之前评估所有这些的好处,因为访问此类数组始终需要确定存储变量的确切类型,然后才能使用该值。看来您对解决方案的设计过度了。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.