Template Class Specialization help
Apr 19, 2011 at 6:09pm UTC
I've been trying to do this for the last 3 days and haven't made any progress. I'm making an array class into a template, and got that to work fine, but I need to change the constructor if the type is a string. No matter what I try, I can't get full or partial specialization to work. The class works fine if I take out the attempt at specialization.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
template < typename T >
class Array
{
friend ostream &operator << <T>( ostream &, const Array<T> & ); // <T>?
friend istream &operator >> <T>( istream &, Array<T> & );
private :
int size;
T* ptr;
public :
Array( int arraySize = 10 );
Array( const Array<T> & );
~Array();
int getSize() const ;
const Array &operator =( const Array<T> & );
bool operator ==( const Array<T> & ) const ;
bool operator !=( const Array<T> &right ) const
{
return ! ( *this == right );
}
T &operator []( int );
T operator []( int ) const ;
};
template < typename T >
inline Array<T>::Array( int arraySize )
{
size = ( arraySize > 0 ? arraySize : 10 );
ptr = new T[ size ];
for ( int i = 0; i < size; i++ )
ptr[ i ] = 0;
}
inline Array<string>::Array( int arraySize ) // doesn't work!
{
size = ( arraySize > 0 ? arraySize : 10 );
ptr = new string[ size ];
for ( int i = 0; i < size; i++ )
ptr[ i ] = "0" ;
}
template < typename T >
inline Array<T>::Array ( const Array<T> &arrayToCopy )
: size( arrayToCopy.size )
{
ptr = new T[ size ];
for ( int i = 0; i < size; i++ )
ptr[ i ] = arrayToCopy.ptr[ i ];
}
template < typename T >
inline Array<T>::~Array()
{
delete [] ptr;
}
template < typename T >
inline int Array<T>::getSize() const
{
return size;
}
template < typename T >
inline const Array<T>& Array<T>::operator =( const Array<T> &right )
{
if ( &right != this )
{
if ( size != right.size )
{
delete [] ptr;
size = right.size;
ptr = new T[ size ];
}
for ( int i = 0; i < size; i++ )
ptr[ i ] = right.ptr[ i ];
}
return *this ;
}
template < typename T >
inline bool Array<T>::operator ==( const Array<T> &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 >
inline T& Array<T>::operator []( int subscript )
{
if ( subscript < 0 || subscript >= size ) //exception
{
cerr << "\nError: Subscript " << subscript << " out of range" << endl;
exit( 1 );
}
return ptr[ subscript ];
}
template < typename T >
inline T Array<T>::operator []( int subscript ) const
{
if ( subscript < 0 || subscript >= size )
{
cerr << " \nError: Subscript " << subscript << " out of range" << endl;
exit( 1 );
}
return ptr[ subscript ];
}
template < typename T >
istream &operator >> ( istream &input, Array<T> &a )
{
for ( int i = 0; i < a.size; i++ )
input >> a.ptr[ i ];
return input;
}
template < typename T >
ostream &operator << ( ostream &output, const Array<T> &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;
}
Main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <iostream>
#include <string>
#include "Array.h"
using namespace std;
int main()
{
Array< int > tester;
Array< string > breaker;
cout << "ints:\n" << tester;
cout << "strings:\n" << breaker;
cin.get();
return 0;
}
I can't figure out how to do this at all. I'd really appreciate a point in the right direction. These are the errors i'm getting with this attempt:
1 2 3 4 5
1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl
std::<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<class
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)"
(?<<@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@ABV?$Array@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) referenced in function _main
1>c:\users\name\documents\visual studio 2010\Projects\TemplateTester\Debug\TemplateTester.exe : fatal error LNK1120: 1 unresolved externals
Last edited on Apr 19, 2011 at 6:10pm UTC
Apr 19, 2011 at 6:45pm UTC
Try :
1 2 3 4 5 6 7 8
template < typename T >
class Array
{
template <typename T>
friend ostream &operator << ( ostream &, const Array<T> & );
template <typename T>
friend istream &operator >> ( istream &, const Array<T> & ); //const added
NOTE:
The above should work using microsoft (as you are) - BUT
Using <T> for the the operator << and >> overloads may cause a problem when compiling with
GCC/Mingw - you will get error about the clash of typename T with the typename T used for the
class Array.
In which case, you can change the template typenames for the operator << and >> functions
to U or some other letter.
1 2
template <typename U>
friend ostream &operator << ( ostream &, const Array<U> & );
Last edited on Apr 19, 2011 at 6:52pm UTC
Apr 19, 2011 at 7:02pm UTC
I can't believe those 2 were ruining everything. Thank you so much.
Topic archived. No new replies allowed.