单线嵌套在C 中

One-liner for nested for loops in C++

本文关键字:嵌套 单线      更新时间:2023-10-16

在python中我可以做到这一点:

>>> import itertools
>>> for i, j,  in itertools.product(range(3), repeat=2): print i, j
...
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

是否可以在C ?

中具有易于阅读的,非增强版本

范围不可避免,但基于范围的循环非常接近。

#include <iostream>
int main(){
    for (int i:{1,2,3}) { for (int j:{1,2,3}) {std::cout << i << " " << j <<std::endl;}};
}

,或者如果您想使用相同的范围

#include <iostream>
int main(){
    const auto range {1,2,3};
    for (int i:range) {for (int j:range) {std::cout << i << " " << j <<std::endl;}};
}

,只是为了使用std::for_each的乐趣(这也许很难阅读,但没有手写循环)

#include <iostream>
#include <algorithm>
int main(){
    const auto range {1,2,3};
    std::for_each(range.begin(), range.end(), [range](int i) {std::for_each(range.begin(), range.end(), [i](int j) {std::cout << i << " " << j <<std::endl; } ); } );
}

循环示例(更新):

#include <array>
#include <iostream>
#include <utility>
template<int VRange, int VRepCount, int VValueRIndex = VRepCount> class
t_Looper
{
    public: template<typename TAction> static void
    process(::std::array<int, VRepCount> & values, TAction && action)
    {
        for(;;)
        {
            t_Looper<VRange, VRepCount, VValueRIndex - 1>::process(values, ::std::forward<TAction>(action));
            auto & value{values[VRepCount - VValueRIndex]};
            if((VRange - 1) != value)
            {
                ++value;
            }
            else
            {
                value = 0;
                break;
            }
        }
    }
};
template<int VRange, int VRepCount> class
t_Looper<VRange, VRepCount, 0>
{
    private: template<int... VIndexes, typename TAction> static void
    invoke(::std::integer_sequence<int, VIndexes...>, ::std::array<int, VRepCount> const & values, TAction && action)
    {
        action(values[VIndexes]...);
    }
    public: template<typename TAction> static void
    process(::std::array<int, VRepCount> & values, TAction && action)
    {
        invoke(::std::make_integer_sequence<int, VRepCount>(), values, ::std::forward<TAction>(action));
    }
};
template<int VRange, int VRepCount, typename TAction> void
multiloop(TAction && action)
{
    ::std::array<int, VRepCount> values{};
    t_Looper<VRange, VRepCount>::process(values, ::std::forward<TAction>(action));
}
int main()
{
    multiloop<3, 2>([](int i, int j){::std::cout << i << " " << j << ::std::endl;});
    multiloop<3, 4>([](int i, int j, int k, int l){::std::cout << i << " " << j << " " << k << " " << l << ::std::endl;});
    return(0);
}

在线运行此代码

是否可以在C ?

中具有易于阅读的,非促进版本

no

您不能在纯C 中执行此操作。您需要一个库左右。

C 14中有实验范围的扩展名,但即使这样,我也不确定是否可以做到。

如果您不介意在这两个模板函数的帮助下创建自己的.. DOT DOT操作员:

template< int First, int Last , int Step = 1>
int ( &dotdot() )[ ( Step + Last - First ) /  Step ]
{
    static int result[ ( Step + Last - First ) /  Step ];
    for( int index = First; index <= Last; index += Step ){
        result[ ( index - First ) / Step ] = index;
    }
    return result;
}
template< int Last, int First, int Step = 1 >
int ( &dotdot() )[ ( Step + Last - First ) / Step ]
{
    static int result[ ( Step + Last - First ) / Step ];
    for( int index = Last; index >= First; index -= Step ){
        result[ ( Last - index ) / Step ] = index;
    }
    return result;
}

然后您可以:

for( int i : dotdot<0,2>() ) for( int j : dotdot<0,2>() ) std::cout << i << ' ' << j << 'n';

和输出:

0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

用法:

  • dotdot<'a','z'>()a返回到z
  • dotdot<'z','a',2>()z返回到a,步骤为2
  • dotdot<-10,0>()-10返回到0
  • dotdot<-10,10,3>()返回-1010,步骤为3