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

如何推断依赖的非类型模板参数?简化数组模板类实例化

简化std::array作为非类型模板参数的类实例化写法

问题背景

现有一个以std::array为非类型模板参数的C++类模板,用于在编译阶段完成配置校验。当前实例化类时必须同时指定数组大小和数组实例(如MyClass<4, valid_config> a;),但数组大小可从数组参数中自动推导,希望简化为MyClass<config> m;的写法,且不能更换容器类型。

解决方案

方案1:C++20 原生自动推导(推荐)

C++20支持非类型模板参数的占位符类型推导,可以直接让编译器自动推导std::array的大小模板参数,无需手动指定。修改后的代码如下:

#include <array>

// 用auto自动推导std::array的大小参数
template<const std::array<int, auto>& config>
class MyClass
{
public:
    MyClass();
private:
    static constexpr bool configIsValid();
};

template<const std::array<int, auto>& config>
MyClass<config>::MyClass()
{
    static_assert(configIsValid(), "Config size must be greater than 3");
}

template<const std::array<int, auto>& config>
constexpr bool MyClass<config>::configIsValid()
{
    return config.size() > 3;
}

int main()
{
    static constexpr std::array<int, 4> valid_config{1,2,3,4};
    MyClass<valid_config> a; // 仅需传入数组实例,大小自动推导
    
    static constexpr std::array<int, 3> invalid_config{5,6,7};
    // MyClass<invalid_config> b; // 编译失败,触发static_assert校验

    return 0;
}

这种写法利用了C++20的新特性,std::array<int, auto>中的auto会自动匹配数组的实际大小,实例化时只需要传入数组变量即可。

方案2:模板别名包装(兼容C++17及更早)

如果需要兼容C++17或更早版本,可以通过模板别名来包装原类模板,自动推导数组大小:

#include <array>

// 保留原类模板结构不变
template<std::size_t config_size, const std::array<int, config_size>& config>
class MyClass
{
public:
    MyClass();
private:
    static constexpr bool configIsValid();
};

template<std::size_t config_size, const std::array<int, config_size>& config>
MyClass<config_size, config>::MyClass()
{
    static_assert(configIsValid());
}

template<std::size_t config_size, const std::array<int, config_size>& config>
constexpr bool MyClass<config_size, config>::configIsValid()
{
    return config.size() > 3;
}

// 定义模板别名,自动推导数组大小
template<const auto& config>
using MyClassSimple = MyClass<config.size(), config>;

int main()
{
    static constexpr std::array<int, 4> valid_config{1,2,3,4};
    MyClassSimple<valid_config> a; // 使用别名简化实例化
    
    static constexpr std::array<int, 3> invalid_config{5,6,7};
    // MyClassSimple<invalid_config> b; // 编译失败

    return 0;
}

模板别名MyClassSimple会通过config.size()自动获取数组大小,传递给原类模板的config_size参数,从而实现简化实例化的效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 23:22:22