我正在优化一些设置代码。这是一个大型预定义值数组,分为三个嵌套结构。它被定义为
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}}}}
}
}
那么这可能吗?可能我需要一些技巧,但我找不到类似的东西。
完整示例此处
您不能将
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}}}}
}
};
和元素的固定大小。
这个(以及其他一些属性)是由元素的type 强制执行的。理论上,同一个数组中可以存储不同类型但相同大小的元素。要在 C++ 中做到这一点,需要更多代码。
例如,您可以尝试使用std::variant
作为元素类型。它保证相同的大小(使用变体支持的所有类型的最大所需大小 -可能浪费大量内存)并且所有元素的类型相同。 个人注释,如果您允许: 我强烈建议在实现之前评估所有这些的好处,因为访问此类数组始终需要确定存储变量的确切类型,然后才能使用该值。看来您对解决方案的设计过度了。