i do an exercise and i have 2 questions.
the exercise is to take an array example from my c++ book and make it template.

for start my code is this:

#include <iostream>
#include <iomanip>
#include <cstdlib> 
#ifndef ARRAY_H
#define ARRAY_H

using namespace std;

template<typename T,int elements>
class Array
{
 // friend ostream &operator<<( ostream &, const Array & );
 //  friend istream &operator>>( istream &, Array & );
public:
   Array(); 
   Array( const Array & );

   int getSize() const; 

   const Array &operator=( const Array & );
   bool operator==( const Array & ) const; 

   bool operator!=( const Array &right ) const  
   { 
      return ! ( *this == right ); 
   }    

    T &operator[]( int );              

   T operator[]( int ) const;  
private:
   int size; 
   T ptr[elements]; 
};

#endif

template<typename T,int elements>
Array<T,elements>::Array()
{
   size = ( elements > 0 ? elements : 10 ); 

   for ( int i = 0; i < size; i++ )
      ptr[ i ] = 0; 
} 

template<typename T,int elements>
Array<T,elements>::Array( const Array &arrayToCopy ) 
   : size( arrayToCopy.size )
{
   for ( int i = 0; i < size; i++ )
      ptr[ i ] = arrayToCopy.ptr[ i ]; 
} 

template<typename T,int elements>
int Array<T,elements>::getSize() const
{
   return size;
} 
/*
template<typename T,int elements>
const Array &Array<T,elements>::operator=( const Array &right )
{
   if ( &right != this ) 
   {
      if ( size != right.size )
      {
         size = right.size; 
         ptr = T[ size ]; 
      } 
   
      for ( int i = 0; i < size; i++ )
         ptr[ i ] = right.ptr[ i ]; 
   } 

   return *this; 
} 
*/
template<typename T,int elements>
bool Array<T,elements>::operator==( const Array &right ) const
{
   if ( size != right.size )
      return false; 

   for ( int i = 0; i < size; i++ )
      if ( ptr[ i ] != right.ptr[ i ] )
         return false; 

   return true; 
} 

template<typename T,int elements>
T &Array<T,elements>::operator[]( int subscript )
{
   if ( subscript < 0 || subscript >= size )
   {
      cerr << "\nError: Subscript " << subscript 
         << " out of range" << endl;
      exit( 1 ); 
   } 

   return ptr[ subscript ]; 
} 

template<typename T,int elements>
T Array<T,elements>::operator[]( int subscript ) const
{
     if ( subscript < 0 || subscript >= size )
   {
      cerr << "\nError: Subscript " << subscript 
         << " out of range" << endl;
      exit( 1 ); 
   } 

   return ptr[ subscript ]; 
} 
/*
istream &operator>>( istream &input, Array &a )
{
   for ( int i = 0; i < a.size; i++ )
      input >> a.ptr[ i ];

   return input; 
} 

ostream &operator<<( ostream &output, const Array &a )
{
   int i;

   for ( i = 0; i < a.size; i++ )
   {
      output << setw( 12 ) << a.ptr[ i ];

      if ( ( i + 1 ) % 4 == 0 ) 
         output << endl;
   } 

   if ( i % 4 != 0 )
      output << endl;

   return output; 
} 
*/

that way works fine but i have put the equality operator in comment and the overloaded ostream and istream as comments cause i recieve errors and i dont know how to fix it.

and 2nd i awnt to make a template specialization of the class with float so i do that

template<>
class Array <float>
{
 // friend ostream &operator<<( ostream &, const Array & );
 //  friend istream &operator>>( istream &, Array & );
public:
   Array(); 
   Array( const Array & );

   int getSize() const; 

   const Array &operator=( const Array & );
   bool operator==( const Array & ) const; 

   bool operator!=( const Array &right ) const  
   { 
      return ! ( *this == right ); 
   }    

    float &operator[]( int );              

   float operator[]( int ) const;  
private:
   int size; 
   float ptr[elements]; 
};

the question is why is wrong?and where i should put the non type parameter

int elements

?

Recommended Answers

All 2 Replies

Here are a few comments:

By convention, the type for all array sizes (and return value of sizeof()) is the standard size type, which is std::size_t . So, you should probably have:

template < typename T, std::size_t elements >

Your data member that you call "ptr" is a static array, not a pointer (as its name implies). It is important to understand that.

Since you are writing what is essentially a header file, you should NOT have an using namespace std; statement. This is an important guideline and you should learn to obey it sooner rather than later.

Personally, I don't like the use of the bare class template name within the class declaration (and worse, in the definition, if the compiler allows it). What I mean is this in the class declaration:

template<typename T,int elements>
class Array
{
 // ..
   const Array &operator=( const Array & );  //I don't like to see this.
  
   const Array<T,elements>& operator=( const Array<T,elements>& ); // I prefer this.

   //or, even better, this:
   typedef Array<T,elements> self;
   const self& operator=( const self& );

 // ..

When you move outside the class declaration (to write your member function definitions) you should always use the fully specialized name Array<T,elements> instead of the bare template name Array . That probably explains your problem with the assignment operator.

Now, for your first question about the iostream operators. This is a bit of mind-bending problem, that is, if you wish to understand the problem, as opposed to just fixing it. Here is an explanation of the problem that I posted some time ago. If you read that and fix it accordingly, it should solve your problem.

Finally, your "partial template specialization" needs to also include the "elements" argument. Basically, look at it this way, when you define a specialization for a class template, the invocation of the template name should contain all the template arguments of the general template, while the template argument statement should contain all unspecialized arguments of the partial template specialization. In other words, these specialization syntaxes are possible:

//This is a "full template specialization":
template <>
class Array< float, 3 > {
  // ..
};

//And this is a "partial template specialization":
template < std::size_t elements >
class Array< float, elements > {
  // ..
};

I hope the above is clear enough. If not, these IBM pages are also very instructive on template specializations.

thanks a lot for your answer,studying only from a book is not always easy, that's why i love this forum :D

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.