如何在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
相关产品推荐
相关产品推荐

