Thread: Template Array Class

  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    72

    Template Array Class

    Hello.. I need a little help getting pointed in the right direction on an exercise that I am working on. I am attempting to create a templated Array class. In the process of this, I need to overload the arithmetic operators (+ and -), the i/o streams, subscript operators, and assignment operators.

    Right now, I am just trying to focus on one part of that at a time. I want to try and get the ostream << operator running right, but I can't quite seem to get it.

    Below is my code;

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <class Type, MAX_ELEMENTS>
    class Array
    {
    protected:
    	Type *pTypeArray;
    public:
    	Array() {pTypeArray=new Type[ MAX_ELEMENTS ];}
    
    	~Array() {delete[] pTypeArray;}
    
    
    	friend ostream& operator <<(ostream&, const Array &);
    	
    };
    
    template <class Type>
    ostream &operator<<(ostream &output, const Array<Type, MAX_ELEMENTS> &a){
    	// I know something else goes here, but not sure of the exact syntax
    	return output;
    }
    
    
    // Main function used to test Array class implementation
    // Attempting to create an Array of 10 ints, then loop through
    // each and assign them with values of 0 through 9, then 
    // have the output be printed out.
    int main()
    {
    	Array<int,10> test;
    	int i;
    
    	for (i=0; i <10; i++)
    	{
    		test[i]=i;
    		cout << test[i];
    	}
        
    	
    	return 0;
    }
    I am getting the following errors when compiling:
    Code:
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(5) : error C2061: syntax error : identifier 'MAX_ELEMENTS'
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(21) : error C2065: 'MAX_ELEMENTS' : undeclared identifier
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(30) : error C2977: 'Array' : too many template arguments
            C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(18) : see declaration of 'Array'
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(30) : error C2079: 'test' uses undefined class 'Array<int>'
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(35) : error C2109: subscript requires array or pointer type
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(35) : error C2106: '=' : left operand must be l-value
    C:\Program Files\Microsoft Visual Studio\MyProjects\CS468_MiniProject1\MiniProject1.cpp(36) : error C2109: subscript requires array or pointer type
    Error executing cl.exe.
    I am hoping that someone can point me/lead me in the right direction. I by no means want someone to simply give me the answer.. I just need a gentle nudge.

    Thanks in advance for your help!

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You need this in both places:
    Code:
    template <class Type, int MAX_ELEMENTS>
    It still won't compile since you haven't defined your subscript operator "[]" yet.

    gg

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >>// I know something else goes here, but not sure of the exact syntax
    Just pretend "output" is actually "cout" and do what you would normally do.

    gg

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    I'm getting closer on this.. I got the subscript operator overloaded, the along with the + and - operators. I also have the assignment operator and the ostream >> overloaded. I just need to overload the equality (i.e. ==) operator and the comparison operators (> and < ) I am working on the equality operator right now, but am having some snags.

    Code below:
    Code:
    #include <iostream>
    
    using namespace std;
    
    template <class Type> class Array;
    
    template <class Type>
    class Array {				
        Type *data;				// an array of length cap
    
      public:
        int cap;				// capacity of array
        int n;				// number currently in array
    					// must satisfy 0<=n<=cap
    
        Array<Type>();			// create an empty array
        
        int num() const			// number of elements in array
    	{return n;}
        
        Type &operator[](int i);		// array indexing, for assignment
    
        Type operator +(const Array<Type> &a)
    	{
    		Array<Type> y(cap);
    		for(int i = 0; i < cap; i++)
    			y[i] = data[i]+a[i];
    		return y;
    	}
        
    	Type operator -(const Array<Type> &a)
    	{
    		Array<Type> y(cap);
    		for(int i =0; i < cap; i++)
    			y[i] = data[i]-a[i];
    		return y;
    	}
    
    	Type & operator =(Array<Type> x){
           n = x.cap;
           data = new int[n];
           for(int i = 0; i < cap; i++)
    	   {
             data[i] = x[i];
    	   }
           return *this;
           }
    
       int operator ==(const Array &) const;
      
    
     
    }; 
    
    template <class Type>
    Array<Type>::Array() {
        cap = 8;	// default array capacity
        data = new Type[cap];
        n = 0;
    };
    
    template <class Type>
    int Array<Type>:: operator ==(const Array<Type> &x ) const {
    	   if (cap != x.cap)
    		   return 0;
    	  
    		for (int i = 0; i < cap; i++)
    		{
    			if cap[i] != x.cap[i]  
    			{
    				return 0;
    			} 
    		return 1;
    		}
    	}
    
    template <class Type>
    Type &Array<Type>::operator[](int i) {
        // this version is used for assignment, e.g. "Array<int> a; a[i] = 7;"
        if (i<0) {
    	cerr << "Array<Type>::operator[](" << i << ")" << endl;
    	exit(1);
        }
        if (i>=n) {
    	if (i>=cap) {
    	    int newcap = cap*2;
    	    if ((i+1)*3/2>newcap) newcap = (i+1)*3/2;
    	}
    	n = i+1;
        }
        return data[i];
    }
    
    
    // to support the following, the caller must supply
    // ostream &operator<<(ostream &s, const Type &x) {	// print item
    
    template <class Type>
    ostream &operator<<(ostream &s, const Array<Type> &a) {	// print array
        s << "array n=" << a.num() << " cap=" << a.cap << ": ";
        int i;
        for (i=0; i<a.num(); i++)
    	s << "[" << i << "]=" << a[i] << ", ";
        s << "end" << endl;
        return s;
    }
    
    int main()
    {
    	Array<int> test,test2;
    	int i;
    
    	for (i=0; i<8; i++)
    	{
    		test[i]=i;
    		cout << test[i];
    	}
    
    	test2 == test;
    
    	for (i=0; i<8; i++)
    	{
    		cout << test2[i];
    	}
    
    	return 0;
    }
    The stuff that is in main is there to test what I have written thus far.

    When I compile it as shown above, I get the following errors:
    Code:
    :\Program Files\Microsoft Visual Studio\MyProjects\Test\TArray.cpp(69) : error C2061: syntax error : identifier 'cap'
            c:\program files\microsoft visual studio\vc98\include\xmemory(59) : while compiling class-template member function 'int __thiscall Array<int>::operator ==(const class Array<int> &) const'
    C:\Program Files\Microsoft Visual Studio\MyProjects\Test\TArray.cpp(70) : error C2143: syntax error : missing ';' before '{'
            c:\program files\microsoft visual studio\vc98\include\xmemory(59) : while compiling class-template member function 'int __thiscall Array<int>::operator ==(const class Array<int> &) const'
    Error executing cl.exe.
    
    CS468_Assignment1.exe - 2 error(s), 0 warning(s)
    Any guidance that anyone can offer would be greatly appreciated. Also, if anyone can help point me in the right direction for the comparison operators, that'd be great too.. Finally, if there are any issues or errors with the rest of the code that perhaps I haven't discovered yet, I'd love to know about those as well...

    Thanks as always!!

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> TArray.cpp(69) : error C2061: syntax error : identifier 'cap'
    What's on line 69? (giggle)
    What's your best guess as to why there's a syntax error on that line?

    >> Array<Type> y(cap);
    This uses a constructor that takes a single integer parameter - which you have not defined.

    If you're going to overload operators, you first need to define what those operators mean.
    For example, if you have the following arrays:
    A = [1, 2, 3, 4, 5]
    B = [1, 2, 3]
    Then what are the results of these:
    A - B
    B - A
    A + B
    A == B
    A < B
    etc.....

    Once you know what your operators are supposed to do, then write code to implement that behavior.

    gg

  6. #6
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    I have part of this figured out I think... I am having issues with instantiating an array of char and then comparing arrays of different sizes... see below:

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <class Type> class Array;
    
    template <class Type>
    class Array {				
        Type *data;				// an array of length cap
    
      public:
        int cap;				// capacity of array
        Type t;				
    
        Array<Type>();			// create an empty array
    
    	Array<Type>(int elements);  // Overloaded constructor to take custom amount of elements
        
        int num() const			// number of elements in array
    	{return t;}
        
        Type &operator[](int i);		// array indexing, for assignment
    
        Type operator +(const Array<Type> &a)
    	{
    		Array<Type> y(cap);
    		for(int i = 0; i < cap; i++)
    			y[i] = data[i]+a[i];
    		return y;
    	}
        
    	Type operator -(const Array<Type> &a)
    	{
    		Array<Type> y(cap);
    		for(int i =0; i < cap; i++)
    			y[i] = data[i]-a[i];
    		return y;
    	}
    
    	Type & operator =(Array<Type> x){
           t = x.cap;
           data = new Type[t];
           for(int i = 0; i < cap; i++)
    	   {
             data = x[i];
    	   }
           return *this;
           }
    
    
    //   Array &operator= ( const Array<Type>& );	
    
       bool operator ==(const Array<Type> &) const;
      
       bool operator > (const Array<Type> & ) const;
    
       bool operator < (const Array<Type> & ) const;
     
    private:
      void copy( const Array<Type> & );
    }; 
    
    template <class Type>
    Array<Type>::Array() {
        cap = 8;	// default array capacity
        data = new Type[cap];
        
    };
    
    
    
    
    /*template <class Type>
    Array<Type> &Array <Type>::operator= (const Array<Type> &rhs)
    {
       delete [] data;
    
       cap = rhs.num();
    
       data = new Type[cap];
    
       for (int K = 0; K < cap; K++)
    
          data[K] = rhs.data[K];
    
       return *this;
    }
    */
    template <class Type>
    Array<Type>::Array<Type>(int elements) {
    	cap = elements;
    	data = new Type[cap];
    	
    };
    
    template <class Type>
    bool Array<Type>:: operator ==(const Array<Type> &x ) const {
    	   if (data != x.data)
    	   {
    		   return true;
    	   } else {
    		 
    		return false;
    		}
    	}
    
    template <class Type>
    bool Array<Type>:: operator >(const Array<Type> &x) const {
    	   return (data > x.data);
    }
    
    template <class Type>
    bool Array<Type>::operator <(const Array<Type> &x) const {
    	return (x.data < data);
    }
    
    
    template <class Type>
    Type &Array<Type>::operator[](int i) {
        // this version is used for assignment, e.g. "Array<int> a; a[i] = 7;"
        if (i<0) {
    	cerr << "Array<Type>::operator[](" << i << ")" << endl;
    	exit(1);
        }
        if (i>=t) {
    	if (i>=cap) {
    	    int newcap = cap*2;
    	    if ((i+1)*3/2>newcap) newcap = (i+1)*3/2;
    	}
    	t = i+1;
        }
        return data[i];
    }
    
    
    // to support the following, the caller must supply
    // ostream &operator<<(ostream &s, const Type &x) {	// print item
    
    template <class Type>
    ostream &operator<<(ostream &s, const Array<Type> &a) {	// print array
        s << "array n=" << a.num() << " cap=" << a.cap << ": ";
        int i;
        for (i=0; i<a.num(); i++)
    	s << "[" << i << "]=" << a[i] << ", ";
        s << "end" << endl;
        return s;
    }
    
    int main()
    {
    	Array<int> test,test2,test3;
    	int i;
    
    	cout << "Test Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test[i]=i;
    		cout << test[i];
    	}
    	
    	cout << "\nTest2 Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test2[i]=i;
    		cout << test2[i];
    	}
    
    	cout << "\nTest3 Integer Array output:\n";
    
    	for (i=0; i<5; i++)
    	{
    		test3[i]=i;
    	    cout << test3[i];
    	}
            cout << "\n";
    
    	if (test == test2)
    	{
    		cout << "We have a match!\n";
    	} else {
    		cout << "Sorry, no match!\n";
        }
    
    	if (test3 > test)
    	{ 
    		cout << "Test3 is the bigger array.\n";
    	} else {
    		cout << "Test is the bigger array.\n";
    	}
    
    	Array<char> chartest="blah";
    	Array<char> chartest2="blah2";
    
    	
    	
    
    	
    
    	if (chartest == chartest2)
    	{
    		cout << "We have a match between chartest and chartest2! \n";
    	} else {
    		cout << "No match between chartest and chartest2!\n";
    	}
    	
    
     
    	return 0;
    }
    When I comment out the whole section about the char arrays, it runs fine. When I include the char array section, I get the following errors:

    Code:
    :\Program Files\Microsoft Visual Studio\MyProjects\test\TArray.cpp(193) : error C2440: 'initializing' : cannot convert from 'char [5]' to 'class Array<char>'
            No constructor could take the source type, or constructor overload resolution was ambiguous
    C:\Program Files\Microsoft Visual Studio\MyProjects\test\TArray.cpp(194) : error C2440: 'initializing' : cannot convert from 'char [6]' to 'class Array<char>'
            No constructor could take the source type, or constructor overload resolution was ambiguous
    Error executing cl.exe.
    
    CS468_Assignment1.exe - 2 error(s), 0 warning(s)
    I've tried assigning the values of the char arrays both on the instantiation line (like above) and on separate lines, but I get the same error message either way. Not sure what I am doing incorrectly.... any help that could be offered would be awesome.

    Thanks as always!

  7. #7
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Code:
    Array<char> chartest="blah";
    Array<char> chartest2="blah2";
    You don't have any constructors that take an array of class Type (in this case a character array). You have the default constructor and one that takes an int. When you initialize like that you are calling a constructor. The compiler can't find a constructor that matches. Amazingly, that is exactly what the compiler error says!
    Code:
    Array<char> chartest;
    const char blah[] = "blah";
    for (i = 0; i < 4; i++)
        chartest[i] = blah[i];
    
    Array<char> chartest2;
    const char blah2[] = "blah2";
    for (i = 0; i < 5; i++)
        chartest2[i] = blah2[i];
    That is an example that uses one of the available constructors and then sets the data in the Array similar to how you did it for the ints. The better solution is to create an explicit constructor that takes an array of type Type and its size.

  8. #8
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    Thanks for the response.. I thought I was capturing all templated types with the following overloaded constructor that is currently in my code:

    Code:
    template <class Type>
    Array<Type>::Array<Type>(int elements) {
    	cap = elements;
    	data = new Type[cap];
    	
    };
    I thought this until, of course, I commented it out just for testing/debugging purposes. I then came to realize that this is really doing nothing. I don't understand why this isn't doing what I am expecting. I would expect this to instantiate an Array class of <Type> and allocate the elements passed to it as its capacity. Since it's templated, I would figure that it would work with ints or chars. Any idea where I went wrong?

    Thanks again!

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Here's what you need to understand....
    A call to a constructor is similiar to any other function call - the number of, and type of, the parameters must match up.
    Here's another rule of thumb, a class or struct declared like so:
    MyClass c = a;
    is equivalent to:
    MyClass c(a);
    which looks more like a function call.....that happens to be a constructor.

    In your case, this:
    Array<char> chartest="blah";
    can be rewritten as, and is logically equivalent to:
    Array<char> chartest("blah");

    So putting yourself in the compiler's shoes, you have a single parameter type of "char [5]", and looking at all the available constructors, there's "no constructor that can take the source type".

    So what would be a constructor that can take the source type? Well, you usually don't need a constructor as specific as "Type [5]", but you can provide a constructor that will take an array of Type of any size:
    Code:
    Array<Type>(const Type *array) {...}
    The only problem with this is, how do you know how many elements are in array? Sure....char C-strings are NULL terminated, but what about an array of other types?
    There is a solution to this delima call "template specialization" but I won't go into that (gotta learn algebra before you learn calculus).

    You can use your existing constructors as jlou posted, or provide a more generic method for assigning "raw" arrays. For example:
    Code:
    void Assign(const Type *array, size_t numElements) {...}
    Here, the number of elements are specified so it will work for any Type.

    Now, you can still have a constructor of the form "Array<Type>(const Type *array)", with the understanding that the array must be NULL terminated so that the number of elements in the array can be determined (this assumption is made in the std::string class).

    gg

  10. #10
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    I hate to beat a dead horse on this, but I know I am really close, I just can't quite get it. I've made some modifications to my code (took me about 2 hours to get this far) and I've changed the Array class to take the Type and the number of elements (i.e. Array<char,5> chartest) because I thought this would be what was necessary to use the Assign method that was mentioned in the previous post. I guess I am a little lost as to where I call that Assign method. Here's the code and my questions follow:
    Code:
    #include <iostream>
    
    using namespace std;
    
    
    
    template <class Type, int MAXSIZE>
    class Array {				
     private:
        int mSize;				// capacity of array
        Type data[MAXSIZE];				
     public:
        Array();			// create an empty array
    
    	~Array();
    	
        int num() const;		// number of elements in array
        
    	void Assign(const Type *data,int mSize );
    
        Type &operator[](int i);		// array indexing, for assignment
    
    	Type operator +(const Array<Type, MAXSIZE> &a)
    	{
    		Array<Type,MAXSIZE> y;
    		for(int i = 0; i < mSize; i++)
    			y[i] = data[i]+a[i];
    		return y;
    	}
        
    	Type operator -(const Array<Type, MAXSIZE> &a)
    	{
    		Array<Type,MAXSIZE> y;
    		for(int i =0; i < mSize; i++)
    			y[i] = data[i]-a[i];
    		return y;
    	}
    
    	Type & operator =(Array<Type, MAXSIZE> z){
           for(int i = 0; i < cap; i++)
    	   {
             data = data[i];
    	   }
           return *this;
           }
    
    
       bool operator ==(const Array<Type, MAXSIZE> & ) const;
      
       bool operator > (const Array<Type, MAXSIZE> & ) const;
    
       bool operator < (const Array<Type, MAXSIZE> &) const;
     
    
    }; 
    
    template <class Type, int MAXSIZE>
    Array<Type, MAXSIZE>::Array():mSize(0){
        
    }
    
    template <class Type, int MAXSIZE>
    Array<Type, MAXSIZE>::~Array(){
    }
    
    template <class Type, int MAXSIZE>
    int Array<Type, MAXSIZE>::num() const
    {
    	return mSize;
    }
    
    template <class Type, int MAXSIZE>
    void Array<Type, MAXSIZE>::Assign(const Type *data, int mSize)
    {
    	mSize=MAXSIZE;
        data=Type;
    }
    
    template <class Type, int MAXSIZE>
    bool Array<Type,MAXSIZE>:: operator ==(const Array<Type, MAXSIZE> &z) const {
    	   if (data != z.data)
    	   {
    		   return true;
    	   } else {
    		 
    		return false;
    		}
    	}
    
    template <class Type, int MAXSIZE>
    bool Array<Type, MAXSIZE>:: operator >(const Array<Type, MAXSIZE> &x) const {
    	   return (data > x.data);
    }
    
    template <class Type, int MAXSIZE>
    bool Array<Type,MAXSIZE>::operator <(const Array<Type, MAXSIZE> &x) const {
    	return (x.data < data);
    }
    
    template <class Type, int MAXSIZE>
    Type &Array<Type, MAXSIZE>::operator[](int i) {
           return data[i];
    }
    
    
    
    template <class Type, int MAXSIZE>
    ostream &operator<<(ostream &s, const Array<Type, MAXSIZE> &a) {	// print array
        int i;
        for (i=0; i<a.num(); i++)
    	s << "[" << i << "]=" << a[i] << ", ";
        s << "end" << endl;
        return s;
    }
    
    int main()
    {
    	Array<int,8> test,test2,test3;
    	int i;
    
    	cout << "Test Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test[i]=i;
    		cout << test[i];
    	}
    	
    	cout << "\nTest2 Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test2[i]=i;
    		cout << test2[i];
    	}
    
    	cout << "\nTest3 Integer Array output:\n";
    
    	for (i=0; i<5; i++)
    	{
    		test3[i]=i;
    	    cout << test3[i];
    	}
            cout << "\n";
    
    	if (test == test2)
    	{
    		cout << "We have a match!\n";
    	} else {
    		cout << "Sorry, no match!\n";
        }
    
    	if (test3 > test)
    	{ 
    		cout << "Test3 is the bigger array.\n";
    	} else {
    		cout << "Test is the bigger array.\n";
    	}
    
    	Array<char,5> chartest="blah";
    	
    	Array<char,6> chartest2="blah2";
    
        
    	if (chartest == chartest2)
    	{
    		cout << "We have a match between chartest and chartest2! \n";
    	} else {
    		cout << "No match between chartest and chartest2!\n";
    	}
    	
    
     
    	return 0;
    }
    Question 1 - I made the void Assign function declaration in the class and then defined it below, as opposed to making an inline function within the class. I don't believe that should make any difference, but I wanted to confirm.

    Question 2 - I changed the Assign function slightly in terms of its arguments so that the arguments matched the data that I would be giving it. I think I am on the right track here, but at this point I guess I should confirm.

    Question 3 - I included the code to assign the arguments (*data and mSize) to the Type and MAXSIZE parameters of the array class. My degree of confidence in this portion of my code is not very high, however. Am I on the right track here?

    Question 4 - Once I get the Assign function straightened out, I won't need to call it separately in my code correct? What I mean is, once I instantiante an Array class object, I shouldn't need to do something like the following??:
    [code]
    Array<char,6> chartest="Blah2";
    chartest.Assign();
    [code]

    Lastly, when I comment out the whole section where I am trying to instantiate Array class objects as char's, the code works fine (i.e. it works fine for ints, but not chars). This leads me to believe that the rest of what I'm doing is pretty much on track...

    Sorry to be such a pest about this and so dense, but I am just not quite there.. I know I *must* be close though, right??

    Thanks to everyone for their patience with me thus far...

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Try this:

    Comment out the Assign() method as well as the declarations and code involving char as Type. I don't see that you use Assign() anywhere else in the code as posted, except in the declaration. Therefore I don't think it is your problem at this point, even though it isn't correct as posted. If Assign() is not used anywhere in the program, then the compiler may not compile it, given that this is a templated class (at least mine doesn't under these circumstances) and therefore may not be telling you of errors.
    Code:
    template <class Type, int MAXSIZE>
    void Array<Type, MAXSIZE>::Assign(const Type *data, int mSize)
    {
    mSize=MAXSIZE;
    data=Type;
    }
    in this code you can't assign Type, which a class name, to data, which is a pointer to class Type. Also, the mSize you assign MAXSIZE to above is a local variable to Assign(), not the mSize listed as a private member variable of the class itself.

    I believe this line:

    Array<char,5> chartest="blah";

    requires the use of a non-default constructor, which you haven't defined. Notice that when using int as Type you don't have the equivalent syntax.

    Array<int,8> test;

    This syntax uses the default constructor, which you have declared and defined. Therefore I suspect that this:

    Array<char, 5> chartest;

    would work fine. As I see it you have three choices to place "blah" in data. FIrst, you can develop a non-default constructor. Second, you can finish developing Assign. Third, you can assign each char in "blah" to an individual element of data, like you did with test, test2, and test3.
    Last edited by elad; 04-08-2004 at 12:50 PM.

  12. #12
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    "As I see it you have three choices to place "blah" in data. FIrst, you can develop a non-default constructor"


    When you say non-default constructor, are you saying the same thing as overloading the constructor?

    Thanks!

  13. #13
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Correct. To handle char arrays I'd try overloading the constructor with a declaration like:

    Array(char *);

    and a definition like:
    Code:
    template<class Type, int MAXSIZE>
    Array<Type, int>::Array(char * stringInput) 
    {
       mSize = strlen(stringInput); 
       if(strlen(stringInput) >= MAXSIZE)
      {
    	 cout << "error. not enough memory set aside for input" << endl;
    	 cout << "enter any key to exit" << endl;
    	 char ch;
    	 cin >> ch;
    	 exit(1);
      }
      else
    	 strcpy(data, stringInput);
    }
    I'm not sure it will work, but that's what I'd try.

    In my view, mSize should be the number of elements actuallly in data, tht is the size, rather than MAXSIZE, which is the largest possible number of elements that could be held in data, which is capacity.

    Also, this syntax:

    template<class Type, int MAXSIZE>

    is new to me. I've never seen a known class (int) with a known name of known value (MAXSIZE) used like this. If it is a legal syntax/it's working for you, go for it. It's just new to me is all.

  14. #14
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    Almost there! Got the assignment operator working right now.. for some reason, the == comparison operator (and I would imagine the < and > comparison operators would be the same) are having issues when trying to pass them an array class with char. They do work with ints, though.

    I've compared how I implemented the overloaded ==, >, and < operators to some other examples I've found in books and online and I fail to see where I went wrong. The only thing that comes to mind (because of the error that VC++ is complaining about) is to overload the overloaded operators (if that's even possible) to accomodate chars. This seems to defeat the purpose of templated classes if I have to have multiple overloaded operators/functions for each data type.

    In any event, here's my code and the error message:

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    
    
    template <class Type, int MAXSIZE>
    class Array {				
     private:
        int mSize;				// capacity of array
        Type data[MAXSIZE];				
     public:
        Array();			// create an empty array
    
    	Array(char *); 
    
    	~Array();
          
        int num() const;		// number of elements in array
        
    
        Type &operator[](int i);		// array indexing, for assignment
    
    	Type operator +(const Array<Type, MAXSIZE> &a)
    	{
    		Array<Type,MAXSIZE> y;
    		for(int i = 0; i < mSize; i++)
    			y[i] = data[i]+a[i];
    		return y;
    	}
        
    	Type operator -(const Array<Type, MAXSIZE> &a)
    	{
    		Array<Type,MAXSIZE> y;
    		for(int i =0; i < mSize; i++)
    			y[i] = data[i]-a[i];
    		return y;
    	}
    
    	Type & operator =(Array<Type, MAXSIZE> z){
           for(int i = 0; i < cap; i++)
    	   {
             data = data[i];
    	   }
           return *this;
           }
    
    
       bool operator ==(const Array<Type, MAXSIZE> & ) const;
      
       bool operator > (const Array<Type, MAXSIZE> & ) const;
    
       bool operator < (const Array<Type, MAXSIZE> & ) const;
     
    
    }; 
    
    template <class Type, int MAXSIZE>
    Array<Type, MAXSIZE>::Array():mSize(0){
        
    }
    
    template <class Type, int MAXSIZE>
    Array<Type, MAXSIZE>::~Array(){
    }
    
    template <class Type, int MAXSIZE>
    int Array<Type, MAXSIZE>::num() const
    {
    	return mSize;
    }
    
    template<class Type, int MAXSIZE>
    Array<Type,MAXSIZE>::Array(char * stringInput) 
    {
       mSize = strlen(stringInput); 
       if(strlen(stringInput) >= MAXSIZE)
      {
    	 cout << "error. not enough memory set aside for input" << endl;
    	 cout << "enter any key to exit" << endl;
    	 char ch;
    	 cin >> ch;
    	 exit(1);
      }
      else
    	 strcpy(data, stringInput);
    }
    
    template <class Type, int MAXSIZE>
    bool Array<Type,MAXSIZE>:: operator ==(const Array<Type, MAXSIZE> &z) const {
    	   if (mSize != z.mSize)
    	   {
    		   return false;
    	   } else {
    		 
    		return true;
    		}
    	}
    
    template <class Type, int MAXSIZE>
    bool Array<Type, MAXSIZE>:: operator >(const Array<Type, MAXSIZE> &x) const {
    	   return (data > x.data);
    }
    
    template <class Type, int MAXSIZE>
    bool Array<Type,MAXSIZE>::operator <(const Array<Type, MAXSIZE> &x) const {
    	return (x.data < data);
    }
    
    template <class Type, int MAXSIZE>
    Type &Array<Type, MAXSIZE>::operator[](int i) {
           return data[i];
    }
    
    
    
    template <class Type, int MAXSIZE>
    ostream &operator<<(ostream &s, const Array<Type, MAXSIZE> &a) {	// print array
        int i;
        for (i=0; i<a.num(); i++)
    	s << "[" << i << "]=" << a[i] << ", ";
        s << "end" << endl;
        return s;
    }
    
    int main()
    {
    	Array<int,8> test,test2,test3;
    	int i;
    
    	cout << "Test Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test[i]=i;
    		cout << test[i];
    	}
    	
    	cout << "\nTest2 Integer Array output:\n";
    
    	for (i=0; i<8; i++)
    	{
    		test2[i]=i;
    		cout << test2[i];
    	}
    
    	cout << "\nTest3 Integer Array output:\n";
    
    	for (i=0; i<5; i++)
    	{
    		test3[i]=i;
    	    cout << test3[i];
    	}
            cout << "\n";
    
    	if (test == test2)
    	{
    		cout << "We have a match!\n";
    	} else {
    		cout << "Sorry, no match!\n";
        }
    
    	if (test3 > test)
    	{ 
    		cout << "Test3 is the bigger array.\n";
    	} else {
    		cout << "Test is the bigger array.\n";
    	}
    
    	Array<char,5> chartest="blah";
    	
    	Array<char,6> chartest2="blah2";
    
        
    	for (i=0; i<5; i++)
    	{
    		cout << chartest[i];
    	}
    
    	if (chartest == chartest2)
    	{
    		cout << "We have a match between chartest and chartest2! \n";
    	} else {
    		cout << "No match between chartest and chartest2!\n";
    	}
    	
    
     
    	return 0;
    }
    And the error msg:
    Code:
    C:\Program Files\Microsoft Visual Studio\MyProjects\test\TArray.cpp(181) : error C2679: binary '==' : no operator defined which takes a right-hand operand of type 'class Array<char,6>' (or there is no acceptable conversion)
    Error executing cl.exe.
    Other than overloading the already overloaded operator (which seems silly and I don't think would work), I am not sure what else I can do to address this error. Any ideas would be awesome..

    Thanks again!!!!!!

  15. #15
    Registered User
    Join Date
    Mar 2003
    Posts
    72
    Hello, I should also mention that it looks like I am having the exact same problem as specifiifed in my previous post when I try to use the < and > overloaded comparison operators as well, and not just the == comparison operator. I would imagine that the solution for one would be the solution for all 3 operators, it's just a matter of realizing what the solution is...

    Any help that anyone can offer would be awesome, as always!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  4. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM