Thread: Type and nontype parameters w/overloading

  1. #1
    Registered User
    Join Date
    Jan 2004
    Posts
    2

    Type and nontype parameters w/overloading

    I have an assignment to create a template for a predefined Array
    class by using a type parameter and a nontype parameter. The
    problem I am having is with my overloaded operators and copy
    constructor. My overloaded operators give me an error that
    states: "no operator defined which takes a right-hand operand of
    type 'class Array<int,10>' (or there is no acceptable
    conversion)". My test program gives me the following error when
    I attempt to use the copy constructor: "use of class template
    requires template argument list."

    Could someone tell me where I am going wrong?

    Here is my code and the applicable portions of the test program.

    <header>
    Code:
    template< class elementType, int numberOfElements = 10 >
    class Array {
    ..
    
    public:
       Array();       // default constructor
       Array( const Array & );  // copy constructor
       ~Array();                // destructor
       int getSize() const;     // return size
    
       // assignment operator
       const Array &operator=( const Array & ); 
       
       // equality operator
       bool operator==( const Array & ) const;  
    
       // inequality operator; returns opposite of == operator
       bool operator!=( const Array &right ) const  
       { 
          return ! ( *this == right ); // invokes Array::operator==
       
       } // end function operator!=
    
    
    <definition>
    
    // copy constructor for class Array;
    // must receive a reference to prevent infinite recursion
    template< class elementType, int numberOfElements >
    Array< elementType, numberOfElements >::Array ( const Array &arrayToCopy )
    	:size( numberOfElements )
    {
       ptr = new elementType[ size ]; // create space for array
    
       for ( int i = 0; i < size; i++ )
          ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object
    
    } // end Array copy constructor
    
    // overloaded assignment operator;
    // const return avoids: ( a1 = a2 ) = a3
    template< class elementType, int numberOfElements >
    const Array< elementType, numberOfElements > &Array< elementType, numberOfElements >::operator=( 
    		const Array &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 elementType[ size ]; // create space for array copy
             
          } // end inner if
    
          for ( int i = 0; i < size; i++ )
             ptr[ i ] = right.ptr[ i ];  // copy array into object
    
       } // end outer if
    
       return *this;   // enables x = y = z, for example
    
    } // end function operator=
    
    // determine if two arrays are equal and
    // return true, otherwise return false
    template< class elementType, int numberOfElements >
    bool Array< elementType, numberOfElements >::operator==( const Array &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
    
    } // end function operator==
    
    
    <test program>
    ..
       Array< int, 7 > integers1;  // seven-element Array
       Array< int > integers2;       // 10-element Array by default
    
    ..
       // use overloaded inequality (!=) operator
       cout << "\nEvaluating: integers1 != integers2\n";
    
       if ( integers1 != integers2 )
          cout << "integers1 and integers2 are not equal\n";
    
    ..
       // create array integers3 using integers1 as an
       // initializer; print size and contents
       Array integers3 ( integers1 );  // calls copy constructor
    
    ..
       // use overloaded assignment (=) operator
       cout << "\nAssigning integers2 to integers1:\n";
       integers1 = integers2;  // note target is smaller
    Last edited by Mr_LJ; 01-01-2004 at 11:25 PM.

  2. #2
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    you currently only have your operators and copy constructors set up to work with arrays of the same length and type. if you want them to work with arrays of other types, then you'll have to template those member functions (so you'll have templated member functions in a templated class). Be careful with attempting assignments and such to templated types if you plan on allowing assigments between arrays of different size and one array is larger than the other, then you'll either have to truncate or use garbage (depending on if the right hand operand is bigger or smaller). Because of this you probably shouldn't even allow for this operation (unless for some reason you are required to). Also, since you template the size of the array, I recommend not using dynamic memory allocation. Instead, just encapsulate an array of the appropriate size. Don't use dynamic memory allocation unless it is truely necessary.

  3. #3
    Registered User
    Join Date
    Jan 2004
    Posts
    2
    Thanks for the reply. That answers a lot. But, it still doesn't help me with the copy constructor. Maybe the problem is in my test program. This is the line my test program uses:

    Code:
       Array integers3 ( integers1 );  // calls copy constructor
    This is my copy constructor:

    Code:
    // copy constructor for class Array;
    // must receive a reference to prevent infinite recursion
    template< class elementType, int numberOfElements >
    Array< elementType, numberOfElements >::Array ( const Array &arrayToCopy )
    	:size( numberOfElements )
    {
       ptr = new elementType[ size ]; // create space for array
    
       for ( int i = 0; i < size; i++ )
          ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object
    
    } // end Array copy constructor

  4. #4
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Originally posted by Mr_LJ
    Code:
       Array integers3 ( integers1 );  // calls copy constructor
    There you're not even specifying template parameters for Array.

    Assuming you fix that, again, you have to make a templated constructor. Right now it's just a constructor of a templated class which takes the same type, so it will only allow for a copy of the same type and length. If you want it to copy an array of different types or of different length, then you have to make a templated constructor as well.

Popular pages Recent additions subscribe to a feed