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

如何对constexpr std::array的每个元素调用模板函数?

编译期遍历constexpr std::array并调用模板函数

已知存在模板函数print<size_t>(void),以及constexpr std::array<size_t,3> q={1,2,3},需要遍历q并对其中每个元素qi调用print<qi>()。以下是尝试过的无法编译的示例代码:

#include<iostream>
#include<array>

template<size_t n>
void print(){ std::cout << n << "\n"; }

template< size_t N, const std::array<const size_t,N> q>
constexpr void print_long(){
    // I) 无法编译:q[i]不是编译期常量表达式
    for(size_t i=0;i<N;++i){ print<q[i]>(); }
    // II) 无法编译:it++会修改constexpr变量,且迭代器递增操作无法在编译期保证是常量表达式
    constexpr auto it = q.begin();
    while(it!=q.end()){ print<*(it++)>(); }
    // III) 无法编译:std::for_each不是constexpr函数(C++17及之前),且lambda参数it无法作为模板实参
    std::for_each(q.begin(),q.end(),[](const auto& it){ print<it>(); });
}

int main(){
    constexpr size_t N=3;
    constexpr std::array<const size_t,N> q={1,2,3};
    print_long<N,q>();
}

解决方案

方案1:C++17兼容(索引序列展开)

利用编译期索引序列和折叠表达式实现,兼容性强:

#include<iostream>
#include<array>
#include<utility>

template<size_t n>
void print(){ std::cout << n << "\n"; }

// 辅助函数:通过索引序列展开调用
template<size_t N, const std::array<const size_t,N>& q, size_t... Is>
constexpr void print_long_impl(std::index_sequence<Is...>) {
    // 折叠表达式依次调用每个索引对应的模板函数
    (print<q[Is]>(), ...);
}

template<size_t N, const std::array<const size_t,N>& q>
constexpr void print_long(){
    print_long_impl<N, q>(std::make_index_sequence<N>{});
}

int main(){
    constexpr size_t N=3;
    constexpr std::array<const size_t,N> q={1,2,3};
    print_long<N,q>();
}

原理:std::make_index_sequence<N>生成0到N-1的编译期索引,Is是编译期常量,因此q[Is]可作为模板实参,折叠表达式会展开为print<q[0]>(); print<q[1]>(); print<q[2]>();。

方案2:C++20及以上(constexpr for)

写法最简洁直观,接近你最初的期望逻辑:

#include<iostream>
#include<array>

template<size_t n>
void print(){ std::cout << n << "\n"; }

template<size_t N, const std::array<const size_t,N>& q>
constexpr void print_long(){
    // C++20 constexpr for的循环变量i是编译期常量
    for(size_t i=0; i<N; ++i) {
        print<q[i]>();
    }
}

int main(){
    constexpr size_t N=3;
    constexpr std::array<const size_t,N> q={1,2,3};
    print_long<N,q>();
}

原理:C++20放宽了constexpr函数的限制,constexpr for的循环变量会被视为编译期常量,因此q[i]可以直接作为模板实参传递给print。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:00:34