Home > Enterprise >  C class templates with multiple arguments
C class templates with multiple arguments

Time:03-30

I am just learning how to use templates in c , and I am struggling a bit. I have an example below, with comments at the points where I'm getting hung up.

#include <iostream>
using namespace std;

template<int arrayOneSize, int arrayTwoSize>
class myClass{
  public:
    myClass(){
        for(int i = 0; i < arrayOneSize; i  ){
        arrayOne[i] = i;
      }
      for(int i = 0; i < arrayTwoSize; i  ){
        arrayTwo[i] = i;
      } 
    }
    
    int arrayOne[arrayOneSize];
    int arrayTwo[arrayTwoSize];
    
    void printArrayElements(){
      for(int i = 0; i < arrayOneSize; i  ){
        cout << arrayOne[i] << '\n';
      }
      for(int i = 0; i < arrayTwoSize; i  ){
        cout << arrayTwo[i] << '\n';
      }
    }
    void someOtherFunction();
};

// can't figure out how to define constructors or functions outside of class
void myClass::someOtherFunction(){

}

template <int numInstances>
class myClassContainer{
  public:
    myClassContainer(){
        for(int i = 0; i < numInstances; i  ){
            myClassInstances[i] = NULL;
        }
    }
    
    // this doesn't work
    template<int, int> myClass<int, int> *myClassInstances[numInstances];
    
    // also doesn't work
    void addClassInstance(myClass *instance){
        for(int i = 0; i < numInstances; i  ){
            if(myClassInstances[i] == NULL){
                myClassInstances[i] = instance; 
            }
        }
    }
    
    void printAll(){
      for(int i = 0; i < numInstances; i  ){
        myClassInstances[i]->printArrayElements();
      }
    }
    
};

int main()
{
    myClass<5,6> myClass1;
    myClass<1,4> myClass2;
    myClassContainer<2> container;
    container.addClassInstance(&myClass1);
    container.addClassInstance(&myClass2);
    container.printArrayElements();

    return 0;
}

I would like to be able to pass pointers to myClass instances into myClassContainer, but I can't figure out the template syntax. Thanks in advance for any advice.

CodePudding user response:

can't figure out how to define constructors or functions outside of class
void myClass::someOtherFunction(){}

The problem here is that there is no class called myClass. Instead, there are only classes called myClass<someNumber, anotherNumber>. So, in order to define someOtherFunction, it must be written something like:

void myClass<someNumber, anotherNumber>::someOtherFunction() { ... }

However, neither someNumber nor anotherNumber are a concrete number, so you need to make them template parameters:

template<int someNumber, int anotherNumber>
void myClass<someNumber, anotherNumber>::someOtherFunction() { ... }

Also note, it's more common and convenient to use the same template names as the ones used in the class declaration, so your definition would be:

template<int arrayOneSize, int arrayTwoSize>
void myClass<arrayOneSize, arrayTwoSize>::someOtherFunction() { ... }

this doesn't work
template<int, int> myClass<int, int> *myClassInstances[numInstances];

The problem here is that the types of all class member must be known at the time the class was defined. So you can not have a member with a template class that cannot deduce its type at the time the outer class is defined. So you need to either:

  1. Assign both template parameters with some concrete value:
template <int numInstances>
class myClassContainer{
    myClass<2, 3> *myClassInstances[numInstances];
};
  1. You can use the template parameter of myClassContainer to calculate a value:
myClass<numInstances, numInstances * 2> *myClassInstances[numInstances];
  1. Or you can make both of them template parameter, and add them to the class template parameters:
template <int numInstances, int A, int B>
class myClassContainer{
    myClass<A, B> *myClassInstances[numInstances];
};
  1. Of course you can do any mixture of them

Do note that whichever approach you decided on, you cannot add both myClass<5, 6> and myClass<1, 4> to the same array, since they are not the same type.


also doesn't work
void addClassInstance(myClass *instance)

Once again, myClass is not a type, instead it must be myClass<someValue, anotherValue>. So you must add the template parameters to the function:

template<int someValue, int anotherValue>
void addClassInstance(myClass<someValue, anotherValue *instance){ ... }

In case you want to define this outside of the class:

template<int numInstances>
template<int someValue, int anotherValue>
void myClassContainer<numInstances>::addClassInstance(myClass<someValue, anotherValue> *instance)
{ ... }
  • Related