sample error:
"Array2.h": Array2.h friend declaration `std:stream& at line 13
operator<<(std:stream&, const Array<T, numberOfElements>&)' declares a non-template function
What could the problem be?
Code:
#ifdef __BORLANDC__
#pragma argsused
#endif
#include <iostream>
using std::cout;
using std::endl;
#include "Array2.h"
int main( int argc, char * argv[])
{
Array<int, 6 > numbers;
cout << numbers.getSize() << endl;
for( int i = 0; i < 6; i++ ){
numbers[i] = i;
}
cout << numbers << endl;
return 0;
}
Code:
// Fig. 8.4: array1.h
// Simple class Array (for integers)
#ifndef ARRAY1_H
#define ARRAY1_H
#include <iostream>
using std::ostream;
using std::istream;
template <class T, int numberOfElements = 10>
class Array {
friend ostream &operator<<( ostream &, const Array<T,numberOfElements> & );
friend istream &operator>>( istream &, Array<T,numberOfElements> & );
public:
Array<T,numberOfElements>(); // default constructor
Array( const Array<T,numberOfElements> & ); // copy constructor
~Array<T,numberOfElements>(); // destructor
int getSize() const; // return size
const Array<T,numberOfElements> &operator=( const Array<T,numberOfElements> & ); // assign arrays
bool operator==( const Array<T,numberOfElements> & ) const; // compare equal
// Determine if two arrays are not equal and
// return true, otherwise return false (uses operator==).
bool operator!=( const Array<T,numberOfElements> &right ) const
{ return ! ( *this == right ); }
T &operator[]( int ); // subscript operator
const T &operator[]( int ) const; // subscript operator
static int getArrayCount(); // Return count of
// arrays instantiated.
private:
int size; // size of the array
T *ptr; // pointer to first element of array
static int arrayCount; // # of Arrays instantiated
};
// Fig 8.4: array1.cpp
// Member function definitions for class Array
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <iomanip>
using std::setw;
#include <cstdlib>
#include <cassert>
//#include "array1.h"
// Initialize static data member at file scope
template <class T, int numberOfElements>
int Array< T,numberOfElements>::arrayCount = 0; // no objects yet
// Default constructor for class Array (default size 10)
template <class T, int numberOfElements >
Array<T,numberOfElements>::Array()
{
size = ( numberOfElements > 0 ? numberOfElements : 10 );
ptr = new T[ size ]; // create space for array
assert( ptr != 0 ); // terminate if memory not allocated
++arrayCount; // count one more object
for ( int i = 0; i < size; i++ )
ptr[ i ] = 0; // initialize array
}
// Copy constructor for class Array
// must receive a reference to prevent infinite recursion
template <class T, int numberOfElements >
Array<T,numberOfElements>::Array( const Array<T,numberOfElements> &init ) : size( init.size )
{
ptr = new T[ size ]; // create space for array
assert( ptr != 0 ); // terminate if memory not allocated
++arrayCount; // count one more object
for ( int i = 0; i < size; i++ )
ptr[ i ] = init.ptr[ i ]; // copy init into object
}
// Destructor for class Array
template <class T, int numberOfElements>
Array<T,numberOfElements>::~Array()
{
delete [] ptr; // reclaim space for array
--arrayCount; // one fewer objects
}
// Get the size of the array
template <class T, int numberOfElements>
int Array<T,numberOfElements>::getSize() const { return size; }
// Overloaded assignment operator
// const return avoids: ( a1 = a2 ) = a3
template <class T, int numberOfElements>
const Array<T,numberOfElements> &Array<T,numberOfElements>::operator=( const Array<T,numberOfElements> &right )
{
if ( &right != this ) { // check for self-assignment
// for arrays of different sizes, deallocate original
// left side array, then allocate new left side array.
if ( size != right.size ) {
delete [] ptr; // reclaim space
size = right.size; // resize this object
ptr = new T[ size ]; // create space for array copy
assert( ptr != 0 ); // terminate if not allocated
}
for ( int i = 0; i < size; i++ )
ptr[ i ] = right.ptr[ i ]; // copy array into object
}
return *this; // enables x = y = z;
}
// Determine if two arrays are equal and
// return true, otherwise return false.
template <class T, int numberOfElements>
bool Array<T,numberOfElements>::operator==( const Array<T,numberOfElements> &right ) const
{
if ( size != right.size )
return false; // arrays of different sizes
for ( int i = 0; i < size; i++ )
if ( ptr[ i ] != right.ptr[ i ] )
return false; // arrays are not equal
return true; // arrays are equal
}
// Overloaded subscript operator for non-const Arrays
// reference return creates an lvalue
template <class T, int numberOfElements>
T &Array<T,numberOfElements>::operator[]( int subscript )
{
// check for subscript out of range error
assert( 0 <= subscript && subscript < size );
return ptr[ subscript ]; // reference return
}
// Overloaded subscript operator for const Arrays
// const reference return creates an rvalue
template <class T, int numberOfElements>
const T &Array<T,numberOfElements>::operator[]( int subscript ) const
{
// check for subscript out of range error
assert( 0 <= subscript && subscript < size );
return ptr[ subscript ]; // const reference return
}
// Return the number of Array objects instantiated
// static functions cannot be const
template <class T, int numberOfElements>
int Array<T,numberOfElements>::getArrayCount() { return arrayCount; }
// Overloaded input operator for class Array;
// inputs values for entire array.
template <class T, int numberOfElements>
istream &operator>>( istream &input, Array<T,numberOfElements> &a )
{
for ( int i = 0; i < a.size; i++ )
input >> a.ptr[ i ];
return input; // enables cin >> x >> y;
}
// Overloaded output operator for class Array
template <class T, int numberOfElements>
ostream &operator<<( ostream &output, const Array<T,numberOfElements> &a )
{
int i;
for ( i = 0; i < a.size; i++ ) {
output << setw( 12 ) << a.ptr[ i ];
if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
output << endl;
}
if ( i % 4 != 0 )
output << endl;
return output; // enables cout << x << y;
}
#endif