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

如何在C++中实现可读性强的模板for循环语法?

实现易读的模板For循环头文件

我希望编写一个头文件,引入后可使用易读的语法编写模板for循环,以下是目标语法示例与判定标准:

目标语法示例

for_loop<int,i0,ic,iE>(i){ // 等价于 for(int i=i0;i<iE;i+=ic),其中i0,ic,iE为constexpr int
   foo(i);
   bar<i>();
   for_loop<int,i,1,10>(j){
      boo<i,j>();
   }
}

判定标准

易读语法需满足:

  • 每个for循环的作用域使用花括号包裹
  • 无冗余代码(无需创建lambda函数、仿函数类、索引序列等不提升可读性的结构)
  • 花括号作用域内对变量和函数的访问权限与传统for循环一致
  • 推荐用<>标识int,i0,ic,iE作为模板参数((i)需借助宏实现符号i)

我的现有实现及问题

以下是目前能正常运行的实现方案:

# define template_for_loop_begin(index) \
    [&]<std::size_t... index>(std::index_sequence<index...>) {

# define template_for_loop_end(index,N) ;}(std::make_index_sequence<N>{});

// 使用方式:
template_for_loop_begin(i)(
  bar<i>(),...
)template_for_loop_end(i,10)

但该语法存在诸多问题:

  • 严重问题:循环体仅限单行
  • 严重问题:循环体必须是单个函数调用
  • 次要问题:行尾需用,...替代;
  • 次要问题:索引信息位于循环末尾
  • 轻微问题:循环使用()而非{}

业务场景背景

以下是客户使用我的样条库的真实代码:

for(int i=0;i<1000;++i){
  int j=i;
  spline.load(j,data[j]);
}

这段代码运行正常,但部分员工写出了如下代码:

for(int i=0;i<500;++i){
  if(data[i]>0){ j=i+500;}else{j=i;}
  spline.load(j,data[i]);
}

我的软件基于运行时自动代码转换生成源码,为保证转换后行为符合预期,索引j必须是constexpr,因此需要将其改为模板实现。但我无法让客户重新学习新的循环写法,以免降低他们的使用意愿,这便是提出此问题的原因。

参考方案的现存问题

感谢Yakk - Adam Nevraumont提供的static_foreach解决方案:

#include <utility>
template<auto first, auto increment, auto limit>
struct static_foreach_t {
  void operator->*( auto f ) const& {
     [&]<auto...Is>(std::integer_sequence<decltype(first), Is...>) {
       ( f( std::integral_constant<decltype(Is), first+Is*increment>{} ), ...);
     }( std::make_integer_sequence< decltype(first), (limit-first)/increment >{} );
  }
};
template<auto first, auto increment, auto limit>
constexpr static_foreach_t<first, increment, limit> static_foreach = {};

// 测试代码
template<typename T>
struct Cxpr{
    const T t;
    consteval Cxpr(T t):t(t){}
};

void foo(int){}
void bar(Cxpr<int>){}
template<int> void boo(void){}

int main(){
    static_foreach<3, 2, 7>->*[&](auto i) {
        foo(i);
        //bar(i); // 取消注释会报错
        boo<i>();
    };
}

但取消注释bar(i);时会报错:error: could not convert 'i' from 'std::integral_constant<int, 3>' to 'Cxpr<int>',尝试多种构造函数和赋值重载仍未解决。此外,该方案无法支持float和double类型,而我的样条库需要断言浮点数为constexpr/consteval类型以避免误用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:47:35