C++ 循环嵌套变量数组合的快速生成

C++ 循环嵌套变量数组合的快速生成,c++,performance,loops,c++11,C++,Performance,Loops,C++11,我有以下代码,它为循环嵌套的变量生成数字/索引的组合 #include <iostream> #include <array> template<size_t ... Rest> inline void index_generator() { constexpr int size = sizeof...(Rest); std::array<int,size> maxes = {Rest...}; std::array<

我有以下代码,它为循环嵌套的变量生成数字/索引的组合

#include <iostream>
#include <array>

template<size_t ... Rest>
inline void index_generator() {
    constexpr int size = sizeof...(Rest);
    std::array<int,size> maxes = {Rest...};
    std::array<int,size> a;
    int i,j;
    std::fill(a.begin(),a.end(),0);

    while(1)
    { 
        for(i = 0; i<size; i++) {
            std::cout << a[i] << " ";
        }
        std::cout << "\n";

        for(j = size-1 ; j>=0 ; j--)
        {
            if(++a[j]<maxes[j])
                break;
            else
                a[j]=0;
        }
        if(j<0)
            break;
    }
}

int main()
{
    index_generator<2,3,3>();
    return 0;
}
这确实相当于

for (int i=0; i<2; ++i)
    for (int j=0; j<3; ++j)
        for (int k=0; i<3; ++k)

for(int i=0;i您可以使用所有维度的乘法的单个循环生成它,并使用模作为最终索引

#include <iostream>
#include <array>

template<size_t ... Rest>
inline void index_generator( ) {
    constexpr int size = sizeof...( Rest );
    std::array<int, size> maxes = { Rest... };
    int total = 1;
    for (int i = 0; i<size; ++i) {
        total *= maxes[i];
    }

    for (int i = 0; i < total; ++i) {
        int remaining = total;
        for (int n = 0; n < size; ++n) {
            remaining /= maxes[n];
            std::cout << ( i / remaining ) % maxes[n] << " ";
        }
        std::cout << std::endl;
    }
}
执行代码

{
    PROFILE_SCOPE( Index1 )
    index_generator1<200, 3, 400, 20>( );
}
{
    PROFILE_SCOPE( Index2 )
    index_generator2<200, 3, 400, 20>( );
}
{
    PROFILE_SCOPE( Index3 )
    index_generator3<200, 3, 400, 20>( );
}

递归模板似乎是个好主意。而且也证明了C++为什么是一种坏语言。但是一个很棒的想法。@ ZBMQ不怪语言,责备程序员。OP显示他特设的模板解决方案比简单的嵌套for循环产生更差的代码。谁的错?@ Matzi的解决方案确实比我所发布的慢得多。您的解决方案的真正问题是使用了两个
除法
s,这消耗了太多的CPUcycles@TasamFarkie我没有对它进行基准测试,但是有两个除法应该不是问题吃与嵌套循环完全相同的东西。@TasamFarkie你是对的。请参阅上面编辑的答案。你有多少个嵌套循环?嵌套循环的数量没有限制。
#include <array>

// Original from the question
template<size_t ... Rest>
inline void index_generator1( ) { 
    constexpr int size = sizeof...( Rest );
    std::array<int, size> maxes = { Rest... };
    std::array<int, size> a;
    int i, j;
    std::fill( a.begin( ), a.end( ), 0 );

    int x = 0;

    while (1) {
        for (i = 0; i < size; i++) {
            x += a[i];
        }

        for (j = size - 1; j >= 0; j--) {
            if (++a[j] < maxes[j])
                break;
            else
                a[j] = 0;
        }
        if (j < 0)
            break;
    }

    LOG( x )
}

// Initial try
template<size_t ... Rest>
inline void index_generator2( ) { 
    constexpr int size = sizeof...( Rest );

    int x = 0;

    std::array<int, size> maxes = { Rest... };
    int total = 1;
    for (int i = 0; i < size; ++i) {
        total *= maxes[i];
    }

    for (int i = 0; i < total; ++i) {
        int remaining = total;
        for (int n = 0; n < size; ++n) {
            remaining /= maxes[n];
            x += ( i / remaining ) % maxes[n];
        }
    }

    LOG(x)
}


// Recursive templates
template <int... Args>
struct Impl;

template <int First, int... Args>
struct Impl<First, Args...>
{
    static int Do( int sum )
    {
        int x = 0;
        for (int i = 0; i < First; ++i) {
            x += Impl<Args...>::Do( sum + i );
        }

        return x;
    }
};

template <>
struct Impl<>
{
    static int Do( int sum )
    {
        return sum;
    }
};

template <int... Args>
void index_generator3( )
{
    LOG( Impl<Args...>::Do( 0 ) );
}
{
    PROFILE_SCOPE( Index1 )
    index_generator1<200, 3, 400, 20>( );
}
{
    PROFILE_SCOPE( Index2 )
    index_generator2<200, 3, 400, 20>( );
}
{
    PROFILE_SCOPE( Index3 )
    index_generator3<200, 3, 400, 20>( );
}
[19:35:50]: 1485600000
[19:35:50]: 1485600000
[19:35:50]: 1485600000

[19:35:56]:          PerCall(ms)
[19:35:56]:   Index1     10.4016
[19:35:56]:   Index2     75.3770
[19:35:56]:   Index3      4.2299