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

如何在C++11中实现将多个任意长度整数序列作为非类型模板参数传入模板类?

实现C++11下的编译期整数序列模板参数

在C++11里确实没法直接把初始化列表{1,2,3}当成非类型模板参数传递,但我们可以用模板元编程的小技巧来实现类似的效果,核心思路是把整数序列封装成一个编译期的类型,再把这个类型作为模板参数传给Foo。下面是具体的实现方案:

方案一:用类型参数封装整数序列(推荐)

这种方式语法更接近你的需求,而且不需要额外定义全局变量,完全在编译期处理:

1. 定义序列封装模板

首先我们写一个可变参数模板,用来持有任意长度的整数序列,同时提供转成std::vector的方法:

#include <vector>
using std::vector;

// 封装任意长度整数序列的模板
template<int... Ints>
struct IntSequence {
    // 编译期转成vector的静态方法
    static vector<int> toVector() {
        return {Ints...};
    }
};

2. 修改Foo模板

让Foo接受两个IntSequence类型作为模板参数,在构造函数里直接调用序列的转vector方法:

void f(vector<int> const & vec1, vector<int> const & vec2) {
    // 这里写你的业务逻辑
}

template<typename Seq1, typename Seq2>
struct Foo {
    Foo(){
        f(Seq1::toVector(), Seq2::toVector());
    }
};

3. 实例化写法

现在你可以这样实例化Foo,语法已经很接近你想要的形式了:

int main(){
    Foo<IntSequence<1,2,3,4>, IntSequence<5,6,7>> foo;
}

如果觉得IntSequence<...>有点繁琐,可以用宏来简化:

#define INT_SEQ(...) IntSequence<__VA_ARGS__>

// 简化后的实例化
Foo<INT_SEQ(1,2,3,4), INT_SEQ(5,6,7)> foo;

方案二:用静态数组作为非类型模板参数

如果你坚持要用非类型模板参数(而不是类型参数),C++11支持将静态constexpr数组的指针作为非类型参数,但需要提前定义全局数组,语法会稍显繁琐:

#include <vector>
using std::vector;

void f(vector<int> const & vec1, vector<int> const & vec2) {
    // 业务逻辑
}

// 提前定义全局的constexpr数组
constexpr int seq1[] = {1,2,3,4};
constexpr int seq2[] = {5,6,7};

// Foo模板接受数组指针和长度作为非类型参数
template<const int* Seq1, size_t Len1, const int* Seq2, size_t Len2>
struct Foo {
    Foo(){
        f(vector<int>(Seq1, Seq1 + Len1), vector<int>(Seq2, Seq2 + Len2));
    }
};

int main(){
    Foo<seq1, sizeof(seq1)/sizeof(seq1[0]), seq2, sizeof(seq2)/sizeof(seq2[0])> foo;
}

扩展:C++20的更简洁方案

如果你的项目可以升级到C20,那事情会简单很多——C20支持将std::array作为非类型模板参数,直接用初始化列表传递:

#include <vector>
#include <array>
using std::vector;
using std::array;

void f(vector<int> const & vec1, vector<int> const & vec2) {
    // 业务逻辑
}

template<array<int, auto> Seq1, array<int, auto> Seq2>
struct Foo {
    Foo(){
        f(vector<int>(Seq1.begin(), Seq1.end()), vector<int>(Seq2.begin(), Seq2.end()));
    }
};

int main(){
    Foo<{{1,2,3,4}}, {{5,6,7}}> foo;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:52:49