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

如何使用可变参数模板初始化constexpr类静态成员?

解决可变参数模板初始化constexpr类成员的问题

你的代码编译失败的核心原因是误用了折叠表达式写法:{( tp_params::val(), ... )} 展开后会变成一个逗号表达式(比如针对test<A,B>,展开结果是(A::val(), B::val())),最终初始化列表里仅存在一个值(逗号表达式的结果为最后一个元素的值),但std::array的大小是2,导致初始化元素数量不匹配,而非单纯的常量表达式合规性问题。

可行解决方法

直接在初始化列表中展开参数包即可,C++17及以上标准支持这种简洁写法:

#include <array>
#include <cstdint>

class A
{
public:
  static constexpr int val() { return 20; }
};

class B
{
public:
  static constexpr int val() { return 30; }
};

template<class... tp_params>
class test
{
protected:
  static constexpr uint32_t count = sizeof...(tp_params);
  // 直接展开参数包,每个tp_params::val()作为array的独立元素
  static constexpr std::array<int, count> m_values = { tp_params::val()... };
};

// 验证代码
int main() {
    constexpr auto& vals = test<A, B>::m_values;
    static_assert(vals[0] == 20);
    static_assert(vals[1] == 30);
    return 0;
}

原理说明

  • tp_params::val()... 会将参数包中的每个类型依次展开,生成对应的val()调用,作为std::array初始化列表的元素,完美匹配array的大小。
  • C++17及以上标准允许static constexpr的std::array直接在类内完成初始化,无需额外的类外定义。

如果需要兼容C++14,可以借助std::index_sequence实现类似功能:

#include <array>
#include <cstdint>
#include <utility>
#include <tuple>

class A
{
public:
  static constexpr int val() { return 20; }
};

class B
{
public:
  static constexpr int val() { return 30; }
};

template<class... tp_params, std::size_t... Idx>
constexpr std::array<int, sizeof...(tp_params)> make_values(std::index_sequence<Idx...>) {
    return { (std::tuple_element_t<Idx, std::tuple<tp_params...>>::val())... };
}

template<class... tp_params>
class test
{
protected:
  static constexpr uint32_t count = sizeof...(tp_params);
  static constexpr std::array<int, count> m_values = make_values<tp_params...>(std::make_index_sequence<count>{});
};

// 验证代码
int main() {
    constexpr auto& vals = test<A, B>::m_values;
    static_assert(vals[0] == 20);
    static_assert(vals[1] == 30);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:03:25