Clean ways to write multiple 'for' loops

前端 未结 16 941
傲寒
傲寒 2020-12-22 15:22

For an array with multiple dimensions, we usually need to write a for loop for each of its dimensions. For example:

vector< vector< vector         


        
16条回答
  •  一生所求
    2020-12-22 15:56

    Firstly, you shouldn't use a vector of vectors of vectors. Each vector is guaranteed to have contiguous memory, but the "global" memory of a vector of vectors isn't (and probably won't be). You should use the standard library type array instead of C-style arrays as well.

    using std::array;
    
    array, 8>, 10> B;
    for (int k=0; k<10; k++)
        for (int i=0; i<8; i++)
            for (int j=0; j<5; j++)
                do_something_on_B(B[k][i][j]);
    
    // or, if you really don't like that, at least do this:
    
    for (int k=0; k<10; k++) {
        for (int i=0; i<8; i++) {
            for (int j=0; j<5; j++) {
                do_something_on_B(B[k][i][j]);
            }
        }
    }
    

    Better yet though, you could define a simple 3D matrix class:

    #include 
    #include 
    
    using std::size_t;
    
    template 
    class matrix3d {
        static_assert(M > 0 && N > 0 && P > 0,
                      "Dimensions must be greater than 0.");
        std::array, N>, M> contents;
    public:
        double& at(size_t i, size_t j, size_t k)
        { 
            if (i >= M || j >= N || k >= P)
                throw out_of_range("Index out of range.");
            return contents[i][j][k];
        }
        double& operator(size_t i, size_t j, size_t k)
        {
            return contents[i][j][k];
        }
    };
    
    int main()
    {
        matrix3d<10, 8, 5> B;
            for (int k=0; k<10; k++)
                for (int i=0; i<8; i++)
                    for (int j=0; j<5; j++)
                        do_something_on_B(B(i,j,k));
        return 0;
    }
    

    You could go further and make it fully const-correct, add matrix multiplication (proper and element-wise), multiplication by vectors, etc. You could even generalise it to different types (I'd make it template if you mainly use doubles).

    You could also add proxy objects so you can do B[i] or B[i][j]. They could return vectors (in the mathematical sense) and matrices full of double&, potentially?

提交回复
热议问题