[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 571
  • Last Modified:

C++ Class Templates with Non-Type Parameters

Hi All,

I would like some help with a class template specialization that includes a non-type parameter. I have managed to do a generic class template for the Array class, which include a non-type parameter N - I have included 3 of the methods below.

The problem I am having is how to specialize for floats. I have included my attempt below, but it's well off the mark as I am getting many compilation errors. I am just not sure of the syntax for specializing class templates and the non-type parameter confuses me further. I though I should rewrite the class definition and replace the T's with floats, but I'm not certain about that anymore either. Can anyone assist?

Many thanks

***HEADER****
template<typename T = int, int N = 10>
class Array {
	
public:
	Array();	   // constructor
	~Array();      // destructor
	int getSize() const;    // returns the number of elements in the array
	bool operator==(const Array<T, N>&) const; // overloaded == operator
	bool operator!=(const Array<T, N>&) const; // overloaded != operator
	T & operator[](int);	// overloaded [] operator
	void inputArray(); 	// eek. not sure what this should do
	void outputArray() const;  // outputs the array to the console
	static int getArrayCount(); // static method to access the arrayCount
	
private:
	T * ptr;	// parametized pointer to an array
	int size; 	// private member holding the number of the elements in the array
	static int arrayCount; // keeps track of how many array 
};
 
************ GENERIC IMPLEMENTATION ***********
// initializing static member in file scope
template<typename T, int N>
int Array<T, N>::arrayCount = 0;
 
// constructor
template<typename T, int N>
Array<T, N>::Array() {
	ptr = new T[N];
	size = N;
	for(int i = 0; i < size; i++)
		ptr[i] = 0;
	arrayCount++;
}
 
// destructor
template<typename T, int N>
Array<T, N>::~Array() {
	delete[] ptr;
}
 
********************************************************************************
************ TEMPLATE SPECIALIZATION FOR FLOAT *****************
 
template<>
int Array<float>::arrayCount = 0;
 
// constructor
template<int N>
Array<float>::Array() {
	ptr = new float[N];
	size = N;
	for(int i = 0; i < size; i++)
		ptr[i] = 0;
	arrayCount++;
}
 
// destructor
template<>
Array<float>::~Array() {
	delete[] ptr;
}
 
***************************************************************************

Open in new window

0
AndreeaN
Asked:
AndreeaN
2 Solutions
 
evilrixSenior Software Engineer (Avast)Commented:
Your specialization is actually a partial specialization so you need to still have N in the template param specification and then define float and N in the specialized specification as part of the class name. It's easier to show than describe so see below.
// Generic
 
template<typename T = int, int N = 10>
class Array {
        
public:
        bool operator==(const Array<T, N>&) const; // overloaded == operator
        bool operator!=(const Array<T, N>&) const; // overloaded != operator
        T & operator[](int);    // overloaded [] operator
        
private:
        T * ptr;        // parametized pointer to an array
        int size;       // private member holding the number of the elements in the array
        static int arrayCount; // keeps track of how many array 
};
 
// Specialization
 
template<int N>
class Array<float, N> {
        
public:
        bool operator==(const Array<float, N>&) const; // overloaded == operator
        bool operator!=(const Array<float, N>&) const; // overloaded != operator
        float & operator[](int);    // overloaded [] operator
        
private:
        float * ptr;        // parametized pointer to an array
        int size;       // private member holding the number of the elements in the array
        static int arrayCount; // keeps track of how many array 
};

Open in new window

0
 
jkrCommented:
That's correct, yet there's still something wrong with the implementation, which needs to be

template<>
int Array<float>::arrayCount = 0;
 
// constructor
template<int N>
Array<float,N>::Array() { // 'N' required here
        ptr = new float[N];
        size = N;
        for(int i = 0; i < size; i++)
                ptr[i] = 0;
        arrayCount++;
}
 
// destructor
template<int N>
Array<float,N>::~Array() { // 'N' required here
        delete[] ptr;
}

See also http://www.cprogramming.com/tutorial/template_specialization.html

The following code compiles:
// Generic
 
template<typename T = int, int N = 10>
class Array {
        
public:
        Array();           // constructor
        ~Array();      // destructor
        int getSize() const;    // returns the number of elements in the array
        bool operator==(const Array<T, N>&) const; // overloaded == operator
        bool operator!=(const Array<T, N>&) const; // overloaded != operator
        T & operator[](int);    // overloaded [] operator
        void inputArray();      // eek. not sure what this should do
        void outputArray() const;  // outputs the array to the console
        static int getArrayCount(); // static method to access the arrayCount
        
private:
        T * ptr;        // parametized pointer to an array
        int size;       // private member holding the number of the elements in the array
        static int arrayCount; // keeps track of how many array 
};
 
template<int N>
class Array<float, N> {
        
public:
        Array();           // constructor
        ~Array();      // destructor
        int getSize() const;    // returns the number of elements in the array
        bool operator==(const Array<float, N>&) const; // overloaded == operator
        bool operator!=(const Array<float, N>&) const; // overloaded != operator
        float & operator[](int);    // overloaded [] operator
        void inputArray();      // eek. not sure what this should do
        void outputArray() const;  // outputs the array to the console
        static int getArrayCount(); // static method to access the arrayCount       
 
private:
        float * ptr;        // parametized pointer to an array
        int size;       // private member holding the number of the elements in the array
        static int arrayCount; // keeps track of how many array 
};
 
//************ GENERIC IMPLEMENTATION ***********
// initializing static member in file scope
// initializing static member in file scope
template<typename T, int N>
int Array<T, N>::arrayCount = 0;
 
// constructor
template<typename T, int N>
Array<T, N>::Array() {
        ptr = new T[N];
        size = N;
        for(int i = 0; i < size; i++)
                ptr[i] = 0;
        arrayCount++;
}
 
// destructor
template<typename T, int N>
Array<T, N>::~Array() {
        delete[] ptr;
}
 
 
//********************************************************************************
//************ TEMPLATE SPECIALIZATION FOR FLOAT *****************
 
template<>
int Array<float>::arrayCount = 0;
 
// constructor
template<int N>
Array<float,N>::Array() {
        ptr = new float[N];
        size = N;
        for(int i = 0; i < size; i++)
                ptr[i] = 0;
        arrayCount++;
}
 
// destructor
template<int N>
Array<float,N>::~Array() {
        delete[] ptr;
}
 
 
//***************************************************************************

Open in new window

0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now