I tried implementing a template Array-class that allows initial size of global arrays to be known at compile time, specified by the user.

When I specify a class of type <1, 1> size, the file compiles fine. However, when I specify a class of any other numeric type, in either "parameter" where both aren't 1, I get this message--

-------------- Build: Debug in Reform_2DArray ---------------

main.cpp
Process terminated with status -1073741819 (0 minutes, 1 seconds)
0 errors, 0 warnings

via Code::Blocks IDE, Microsoft Visual C++ 2005/2008 compiler, on Windows XP.

The code is a modified version of something I posted in someone elses topic. It doesn't quite solve their problem, but it does provide an interesting means of cleanly creating a 2D array at compile time.

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::size_t;
template< size_t, size_t> class TwoDimensional;

template< size_t R, size_t C>
class TwoDimensional{
    private:
        enum {TRUE_R = 2 * TwoDimensional<R-1, 0>::TRUE_R};
        enum {TRUE_C = 2 * TwoDimensional<0, C-1>::TRUE_C};

    //    int dummyArray[TRUE_R][TRUE_C];
    //    int row[TRUE_R][TRUE_C];

    //public:
/*
        TwoDimensional(){
            int myArray[TRUE_C] = {0};// initialize to have 0 in all indices
         //   cout << "Initializing 2Darray to be of 'area' : [" << TRUE_R << " x " << TRUE_C << "]" << endl;
            for(size_t i = 0; i < TRUE_R; i++)
                memcpy(row[i], myArray, TRUE_C * sizeof(int)); // copy contents of myArray into row[i]
        }

        size_t getRowSize(){
            return TRUE_R;
        }

        size_t getColSize(){
            return TRUE_C;
        }

        ostream& showContents(ostream& out = cout){
            for(size_t i = 0; i < TRUE_R; i++){
                for(size_t j = 0; j < TRUE_C; j++)
                    out << row[i][j] << " ";
                out << endl;
            }
            return out;
        }

        int* operator[] (size_t indice){
            if(indice >= 0 && indice < TRUE_R){
                return row[indice];
            }
            return dummyArray[indice];
        }*/
};

template<>
class TwoDimensional<0, 0>{
    public:
        enum{TRUE_R = 1};
        enum{TRUE_C = 1};
};

int main(){

    TwoDimensional<1, 1> td; // error if any other number, other than 1, is enterred for either parameter
 //   td.showContents() << endl;
    cin.ignore();
    cin.get();

    return 0;
}

I've tried changing the access modifier to public, but no luck.

I'm still trying to figure this problem out, but I'm fairly stumped! O_O

Thanks =)

-Alex

Recommended Answers

All 4 Replies

http://tinyurl.com/4xeajm

When I use

TwoDimensional<1, 2> td; // error if any other number, other than 1, is enterred for either parameter

it doesn't quite build for me.

main.cpp:15: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating `class TwoDimensional<-499u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-498u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-497u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-496u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-495u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-494u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-493u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-492u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-491u, 0u>'
...
main.cpp:15: instantiated from `TwoDimensional<-1u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<0u, 1u>'
main.cpp:16: instantiated from `TwoDimensional<1u, 2u>'
main.cpp:64: instantiated from here

main.cpp:15: error: incomplete type `TwoDimensional<-499u, 0u>' used in nested name specifier
main.cpp:15: error: enumerator value for `TRUE_R' not integer constant
main.cpp:16: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating `class TwoDimensional<0u, -1u>'
main.cpp:16: instantiated from `TwoDimensional<-498u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-497u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-496u, 0u>'
...
main.cpp:15: instantiated from `TwoDimensional<-2u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-1u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<0u, 1u>'
main.cpp:16: instantiated from `TwoDimensional<1u, 2u>'
main.cpp:64: instantiated from here

main.cpp:16: error: incomplete type `TwoDimensional<0u, -1u>' used in nested name specifier
main.cpp:16: error: enumerator value for `TRUE_C' not integer constant
main.cpp: In instantiation of `TwoDimensional<-497u, 0u>':
main.cpp:15: instantiated from `TwoDimensional<-496u, 0u>'
...
main.cpp:15: instantiated from `TwoDimensional<0u, 1u>'
main.cpp:16: instantiated from `TwoDimensional<1u, 2u>'
main.cpp:64: instantiated from here
main.cpp:15: error: `TwoDimensional<-498u, 0u>::<anonymous enum> TwoDimensional<-498u, 0u>::TRUE_R' is private
main.cpp:15: error: within this context
main.cpp: In instantiation of `TwoDimensional<0u, -1u>':
main.cpp:16: instantiated from `TwoDimensional<-497u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-496u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-495u, 0u>'
...
main.cpp:15: instantiated from `TwoDimensional<0u, 1u>'
main.cpp:16: instantiated from `TwoDimensional<1u, 2u>'
main.cpp:64: instantiated from here
main.cpp:15: error: incomplete type `TwoDimensional<-1u, 0u>' used in nested name specifier
main.cpp:15: error: enumerator value for `TRUE_R' not integer constant
main.cpp:16: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating `class TwoDimensional<0u, -2u>'
main.cpp:16: instantiated from `TwoDimensional<0u, -1u>'
main.cpp:16: instantiated from `TwoDimensional<-497u, 0u>'
main.cpp:15: instantiated from `TwoDimensional<-496u, 0u>'

...and much, much more.

commented: Whoo! Figured out the error @_@ +4

I get the same compile errors, and it goes into an infinite recursion. I think the problem is trying to pass in the dimensions where the compiler expects type specifiers ?

Perhaps an implementation of TwoDimensional<int> (int rows, int cols) ?

Whoo! O_O

Thanks to those error messages, I was able to track down the issue @_@

Even though I try to safely specify 0 as the argument of the other value, the 2nd argument will be decremented by 1...

for example..

template<1, 2>
{

       enum{
            TRUE_R = 2 * template<0, 0>::TRUE_R /*which equals 1... however...*/ 
       };
       enum{
            TRUE_C = 2 * 
                       template<0, 1>{
                                  
                             enum{TRUE_R = 2 * template<-1, 0>{
                                     /* infinite expansions >_< */
                              }::TRUE_R /*BAD! O_O*/};         
                             
                             enum{TRUE_C = 2 * template<0, 0>::TRUE_C /*which equals 1*/ };
             }::TRUE_C

             

       };


}

Thanks Dave! =)

In case anyone is interested, here's a meta-program solution to the original problem--

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::size_t;
template< size_t, size_t, size_t> class TwoDimensional;
template< size_t, size_t > class Multiplier;

template<>
class Multiplier<0, 0>{
    public:
        enum{TRUE_M = 1};
};

template< size_t Mult, size_t Times>
class Multiplier{
    public:
        enum{TRUE_M = Mult * Multiplier< ( (Times > 0 ) ?  Mult : 0) , ( (Times > 0) ? Times - 1 : 0)>::TRUE_M};
};

template< size_t R, size_t C, size_t M>
class TwoDimensional{
    private:
        enum {TRUE_R = Multiplier<M, R - 1>::TRUE_M};
        enum {TRUE_C = Multiplier<M, C - 1>::TRUE_M};
        enum {AREA = TRUE_R * TRUE_C};

        int dummyArray[TRUE_R][TRUE_C];
        int row[TRUE_R][TRUE_C];

    public:

        TwoDimensional(){
            int myArray[TRUE_C] = {0};// initialize to have 0 in all indices
            for(size_t i = 0; i < TRUE_R; i++)
                memcpy(row[i], myArray, TRUE_C * sizeof(int)); // copy contents of myArray into row[i]
        }

        size_t getRowSize(){
            return TRUE_R;
        }

        size_t getColSize(){
            return TRUE_C;
        }

        size_t getArea(){
            return AREA;
        }

        ostream& showContents(ostream& out = cout){
            for(size_t i = 0; i < TRUE_R; i++){
                for(size_t j = 0; j < TRUE_C; j++)
                    out << row[i][j] << " ";
                out << endl;
            }
            return out;
        }

        int* operator[] (size_t indice){
            if(indice >= 0 && indice < TRUE_R){
                return row[indice];
            }
            return dummyArray[indice];
        }
};


int main(){

    TwoDimensional<3, 4, 2> td;
    td[1][3] = 5;
    td.showContents() << endl;
    cin.ignore();
    cin.get();

    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.