0

I would like to implement a Base class with attributes of a size I already know at compile-time. So my idea was to use a template for this Base class. The following code compiles and runs fine under VC++9.0.

Class definition in the .h file

template<int N> class BaseClass
{
int* idx; 
int* incr; 
int* limit;


public:
BaseClass(void);
~BaseClass(void);

void LoopMethod(void);

};

Implementation of the class methods in the .cpp file

#include "BaseClass.h"
#include<iostream>

using namespace std;

 // instantiation
 template class BaseClass<2>;


template<int N> BaseClass<N>::BaseClass(void)
{
idx = new int [N];
incr= new int [N];
limit = new int[N];

for(int m = 0; m < N; m++)
{
    idx[m] = 0;
    incr[m] = 1;
    limit[m] = 2;
}

}

template<int N> BaseClass<N>::~BaseClass(void)
{
}


template<int N> void BaseClass<N>::LoopMethod( )
{   
for( idx[N-1]; idx[N-1] < limit[N-1]; idx[N-1] += incr[N-1] )
{
    cout << "LoopMethod Nr " << N-1 << " is called." << endl;
}

}

Implementation of the main-function:

#include<cstdlib>
#include "BaseClass.h"

using namespace std;


int main()
{
BaseClass<2> baseObj;

baseObj.LoopMethod();


system("PAUSE");
return 0;

}

Now I want to nest the for-loops from the LoopMethod times the size of the class attributes. I.e. the compiler should generate a code I would write by Hand as

 template<int N> void BaseClass<N>::LoopMethod( )
 {
for( idx[0]; idx[0] < limit[0]; idx[0] += incr[0] )
{   
    for( idx[1]; idx[1] < limit[1]; idx[1] += incr[1] )
    {
        cout << "LoopMethod Nr " << 1 << " is called." << endl;
    }

    cout << "LoopMethod Nr " << 0 << " is called." << endl;

}
 }

Anyway, I can prompt the compiler to do this, if I do not declare the BaseClass to be a template class. The code for this would then look like:

 class BaseClass
 {


int* idx; 
int* incr; 
int* limit;


public:
BaseClass(void);
~BaseClass(void);

template<int M> void LoopMethod(void);


 };

Implementation of the class methods in the .cpp file

#include "BaseClass.h"
#include<iostream>

using namespace std;

template void BaseClass::LoopMethod<1>();           

BaseClass::BaseClass(void)
{
idx = new int [2];
incr= new int [2];
limit = new int[2];

for(int m = 0; m < 2; m++)
{
    idx[m] = 0;
    incr[m] = 1;
    limit[m] = 2;
}

}

BaseClass::~BaseClass(void)
{
}

template<int M> void BaseClass::LoopMethod( )
{
for( idx[M]; idx[M] < limit[M]; idx[M] += incr[M] )
{
    cout << "LoopMethod Nr " << M-1 << " is called." << endl;
    LoopMethod<M-1>();

}
}

template<> void BaseClass::LoopMethod<0>(void)
{
idx[0] = 0;

for( idx[0]; idx[0] < limit[0]; idx[0] += incr[0] )
{
    // do something
    cout << "Now the inner loop is executed" << endl;

}

 }

Implementation of the main-function:

#include<cstdlib>
#include "BaseClass.h"

using namespace std;


int main()
{
BaseClass baseObj;

baseObj.LoopMethod<1>();


system("PAUSE");
return 0;
 }

But the solution I am searching for is to have a template class with a template method “LoopMethod” owing its own template parameter which tells the compiler how many times to nest the for-Loop. I have tried various possibilities but without success. Does anybody have a suggestion or even know a solution for this template problem?

Thanks in advance for your help,

Markus.

Markus
  • 1

2 Answers2

5

There are a lot of issues with your template:

  • What exactly is the purpose of the whole thing?
  • Why are you initialising the pointers with new? You know the size at compile time so why not just make them arrays?
  • You are not deleting the memory you are allocating
  • Exception safety if new fails for one of the later arrays
  • Implementation probably should be in the header file unless it is used for very few values of N which you instantiate
  • Better to use classes that exist that do this kind of thing, eg boost::array
  • Refactor out various sections of it.
CashCow
  • 30,981
  • 5
  • 61
  • 92
0

But the solution I am searching for is to have a template class with a template method “LoopMethod” owing its own template parameter which tells the compiler how many times to nest the for-Loop

Is that what you are asking:

template<int N>
struct X
{
    template<int M>
    void loop();
};

template<int N>
template<int M>
void X<N>::loop<M>()
{
}
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • It looks like he wants to use the template size just for looping therefore he does not need two different template parameter values. If he used vector he would be able to know the size of the collection he is looping over. – CashCow Feb 09 '11 at 10:03