如何编写一个简单的C ++代码来简单地运行具有特定展开因子的for循环? 例如,我需要编写一个for循环,为数组的每个索引赋值i,即A [i] = i表示数组大小,比如1e6。
现在我想添加一个展开因子,比如说20.我不想手动编写20行代码并重复5k次。我该怎么做呢?我是否嵌套我的for循环?如果我使用模板元编程,编译器会自动为我做一些展开吗?如何手动设置展开因子(在编译时固定)?
答案 0 :(得分:2)
以下示例是用 C ++ 17 编写的,但是有一些更详细的技术,这个想法适用于C ++ 11及更高版本。
如果你真的想强制进行一些展开,你可以考虑将lambda传递给这样的模板化函数:
template<auto i, auto N, auto delta, class F>
constexpr void loop(From<i>, Less<N>, By<delta>, F f) noexcept {
if constexpr(i<N) {
f(Val<i>{});
loop(from<i+delta>, less<N>, by<delta>, f);
}
}
要使用它,您可以编写类似
的代码loop(from<100>, to<200>, by<5>, [&] (auto i) {
std::cout << "do something with " << i << std::endl;
});
完整working example(在应用之前考虑):
#include <iostream>
namespace Loop {
template<auto v> using Val = std::integral_constant<decltype(v), v>;
template<auto i> struct From : Val<i> {};
template<auto i> static constexpr From<i> from{};
template<auto i> struct Less : Val<i> {};
template<auto i> static constexpr Less<i> less{};
// `to<i>` implies `less<i+1>`
template<auto i> struct To : Less<i+decltype(i)(1)> {};
template<auto i> static constexpr To<i> to{};
template<auto i> struct By : Val<i> {};
template<auto i> static constexpr By<i> by{};
template<auto i, auto N, auto delta, class F>
constexpr void loop(From<i>, Less<N>, By<delta>, F f) noexcept {
if constexpr(i<N) {
f(Val<i>{});
loop(from<i+delta>, less<N>, by<delta>, f);
}
}
// overload with two arguments (defaulting `by<1>`)
template<auto i, auto N, class F>
constexpr void loop(From<i>, Less<N>, F f) noexcept {
loop(from<i>, less<N>, by<decltype(i)(1)>, f);
}
// overload with two arguments (defaulting `from<0>`)
template<auto N, auto delta, class F>
constexpr void loop(Less<N>, By<delta>, F f) noexcept {
loop(from<decltype(N)(0)>, less<N>, by<delta>, f);
}
// overload with one argument (defaulting `from<0>`, `by<1>`)
template<auto N, class F>
constexpr void loop(Less<N>, F f) noexcept {
using Ind = decltype(N);
loop(from<Ind(0)>, less<N>, by<Ind(1)>, f);
}
} // namespace Loop
int main() {
{
using namespace Loop;
loop(from<100>, to<200>, by<5>, [&] (auto i) {
constexpr int it_is_even_constexpr = i;
std::cout << it_is_even_constexpr << std::endl;
});
}
return 0;
}