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

C++存储constexpr编译期值时如何减少冗余模板参数

解决方案

1. C++17及以上版本(最优方案)

C++17引入了auto非类型模板参数占位符,可直接自动推导值的类型,完全不需要手动指定类型:

template <auto _x1, auto _x2>
struct A
{
    constexpr static decltype(_x1) x1 = _x1;
    constexpr static decltype(_x2) x2 = _x2;
};

使用方式非常简洁,直接传入编译期常量即可:

// 自动推导x1类型为int,x2类型为double
constexpr auto instance = A<10, 3.14>{};
static_assert(instance.x1 == 10);
static_assert(instance.x2 == 3.14);

如果需要存储任意数量的编译期值,可以搭配可变参数模板实现通用存储类:

#include <tuple>

template <auto... Args>
struct ConstexprStore
{
    template <std::size_t Index>
    constexpr static auto get = std::get<Index>(std::make_tuple(Args...));
};

// 使用示例
constexpr auto store = ConstexprStore<1, 2.5f, 'a', true>{};
static_assert(store.get<0> == 1); // int类型
static_assert(store.get<1> == 2.5f); // float类型

C++20中还可以搭配概念对值的类型做约束,比如要求第一个参数是整数、第二个是浮点数:

#include <concepts>

template <std::integral auto _x1, std::floating_point auto _x2>
struct A
{
    constexpr static decltype(_x1) x1 = _x1;
    constexpr static decltype(_x2) x2 = _x2;
};

2. 兼容C11/C14的方案

如果编译环境不支持C++17,可以通过宏包装decltype来避免手动写类型:

// 先定义辅助宏
#define CONSTEXPR_PARAM(val) decltype(val), val

// 原有模板类不需要修改
template <class T1, T1 _x1, class T2, T2 _x2>
struct A
{
    constexpr static T1 x1 = _x1;
    constexpr static T2 x2 = _x2; // 注意你原代码此处笔误写为T1,会导致类型错误
};

// 使用时传入宏包装后的值即可,无需手动写类型
constexpr auto instance = A<CONSTEXPR_PARAM(10), CONSTEXPR_PARAM(3.14)>{};
static_assert(instance.x1 == 10);

补充说明:以上所有实现都完全保留了值的constexpr属性,可正常用于编译期判断、常量表达式计算等场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:15:07