Trouble with Templates

Nov 3, 2010 at 10:56pm
Hi guys, I'm trying to write a simple class using templates, but it's not really working out so well. I wonder if someone could tell me where I'm going wrong?

Here are the relevant parts of "MyArray.h":
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cmath>

template <class T>
class MyArray
{
public:
    MyArray();
    MyArray( const T& value );
    MyArray( int sz, const T& value );
    MyArray( MyArray<T>& x);//copy constructor
    ~MyArray();

    int size()const{ return _size; }
    int capacity()const{ return _capacity; }

    //overload operator
    MyArray<T>& operator= (const MyArray<T>& x);
    T& operator[](int index) const;
};

#include "MyArray.cpp" 


And here is "MyArray.cpp"
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
#include <cmath>

//CONSTRUCTORS
//Default constructor, creates an empty array

template <class T>
MyArray<T>::MyArray()
{
   	_size = 0;
   	_capacity = 1;

   	_data = NULL; //empty array, contains nothing
}

//Creates an array with minimum capacity with value in the first cell
template <class T>
MyArray<T>::MyArray( const T& value )
{
   	_size = 1;
   	_capacity = 1;

   	T* new_array = new T[_capacity];
   	_data = new_array;
   	_data[0] = value;
}

//Creates an array with size sz, a large enough capacity, then put value in all the cells up to sz.
template <class T>
MyArray<T>::MyArray( int sz, const T& value )
{
	_size = sz;
	_capacity = (int)pow(2,(double)ceil(log((double)_size)/log(2.0))+1);

	T* new_array = new T[capacity];
	_data = new_array;

	for(int i = 0; i != _size; ++i)
	{
		_data[i] = value;
	}
}

//Copy constructor
template <class T>
MyArray<T>::MyArray( MyArray<T>& x)
{
	_size = x.size;
	_capacity = x.capacity;

	T* new_array = new T[capacity];

	for(int i = 0; i != _size; ++i)
	{
		new_array[i] = x._data[i];
	}
}

//do this later
template <class T>
MyArray<T>::MyArray( MyArrayPointer<T> first, MyArrayPointer<T> last )
{

}

//DESTRUCTOR
template <class T>
MyArray<T>::~MyArray()
{
	delete [] _data;
}

//OPERATOR OVERLOAD
template <class T>
MyArray::MyArray<T>& operator= (const MyArray<T>& x)
{
	//do later
}

template <class T>
T& MyArray<T>::operator[](int index) const
{
	return _data[index];
}


Here are the error messages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
**** Build of configuration Debug for project PA2 ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -oMyArray.o ..\MyArray.cpp
..\MyArray.cpp:7:1: error: 'MyArray' does not name a type
..\MyArray.cpp:16:1: error: expected unqualified-id before 'template'
..\MyArray.cpp:29:1: error: 'MyArray' does not name a type
..\MyArray.cpp:44:1: error: expected unqualified-id before 'template'
..\MyArray.cpp:60:1: error: 'MyArray' does not name a type
..\MyArray.cpp:66:1: error: expected unqualified-id before 'template'
..\MyArray.cpp:74:1: error: 'MyArray' does not name a type
..\MyArray.cpp:79:1: error: expected unqualified-id before 'template'
Build error occurred, build is stopped
Time consumed: 138  ms.  

Using the Eclipse Helios IDE with g++ on Win7.

I'm totally stuck. I would really appreciate someone's help on this. Thanks in advance!
Last edited on Nov 3, 2010 at 11:21pm
Nov 3, 2010 at 11:00pm
You're missing a closing brace:

1
2
3
4
5
6
//...
    T& operator[](int index) const;

};  // <- put this in 

#include "MyArray.cpp"  


Also, what is 'MyArrayPointer'? I don't see it defined anywhere.
Nov 3, 2010 at 11:06pm
Ah, sorry. I was supposed to be implementing MyArray.cpp, MyArray.h is already given. I only just started, so I cut out the parts that I hadn't started yet. I accidentally missed out a brace and forgot to remove the parts wth MyArrayPointer, which isn't done yet.
Nov 3, 2010 at 11:20pm
You're still missing a semicolon after the closing brace
Nov 3, 2010 at 11:21pm
Sorry. x_x Guess I need more sleep.
Anyway, it didn't seem that any errors were detected in MyArray.h during compilation.
Nov 3, 2010 at 11:43pm
1
2
//MyArray::MyArray<T>& operator= (const MyArray<T>& x)
MyArray<T>& MyArray<T>::operator= (const MyArray<T>& x)


Why capacity = 1 in the default constructor?
Nov 4, 2010 at 7:03am
This is an array that grows and shrinks its capacity by a power of 2 depending on the size. So the smallest capacity is 1.
Nov 4, 2010 at 7:12am
He has another issue here because in his h file he has an #include "MyArray.cpp" directive
but he(or his IDE/project management software) is also trying to compile MyArray.cpp
as a seperate file as well.
g++ -O0 -g3 -Wall -c -fmessage-length=0 -oMyArray.o ..\MyArray.cpp

We don't want to compile MyArray.cpp on it's own merit.

My suggestion is to change MyArray.cpp filename to MyArray.inl
and in the header file #include "MyArray.inl"

((Note he may have other Template related issues))
Nov 4, 2010 at 9:02am
Hi, I'm not very familiar with the Eclipse IDE, so I'm not sure how to change that.
However, I did try compiling just with this line: g++ main.cpp
And I still get this error:

1
2
..\MyArray.cpp:74:1: expected unqualified-id before 'template
..\MyArray.cpp:79:1: error: 'MyArray' does not name a type 
Nov 4, 2010 at 5:29pm
Any help? Sorry guys...
Nov 4, 2010 at 6:21pm
have you tried what I said about re-naming your cpp file??
Nov 4, 2010 at 8:30pm
I'm not allowed to do that in the assignment, sorry. :(
Nov 5, 2010 at 6:36am
Well if your assignment says that the MyArray should be in two parts (h file and cpp file) in the way that you have them, and you have them in an eclipse project -

then you can exclude the MyArray.cpp file from the build process -

you do this by right-click on MyArray.cpp file in the project explorer - select properties - and make sure the exclude resource from build checkbox is ticked (on the the C/C++ Build ->Tool Chain Editor page).
That should stop Eclipse from trying to compile MyArray.cpp as a seperate file..

Also make sure none of your other files (except MyArray.h) include MyArray.cpp.
(They should include MyArray.h).

Should work - I just tried it.

That should just leave you with the C++ syntax and other errors in the code you posted.
Nov 5, 2010 at 12:52pm
Wow! thanks!
Well, for some reason Eclipse is bunging up on me right now (it generally does) but once I figure out what's wrong I'm sure that'll fix it! Thanks!
Nov 5, 2010 at 1:42pm
It all seems to be working fine, except one part. I think I have some syntax error in this part.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T>
MyArray::MyArray<T>& operator= (const MyArray<T>& x)
{
	_size = x._size;
	_capacity = x._capacity;

	delete [] _data; //prevent memory leak
	_data = new T[_capacity];

	for(int i = 0; i != _size; ++i)
	{
		_data[i] = x._data[i];
	}
}
Nov 5, 2010 at 7:58pm
I'm glad you noticed those memory leaks.

The assignment operator function should return a value and it should ensure that it is not
trying to copy itself to itself.

here is a reminder:
http://www.fredosaurus.com/notes-cpp/oop-overloading/overloadassign.html

remember to change your function prototype in MyArray.h as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class T>
MyArray<T>& MyArray<T>:: operator= (const MyArray<T>& x)
{
    if (this != &x)
   {
        _size = x._size;
        _capacity = x._capacity;

        delete [] _data; //prevent memory leak
       _data = new T[_capacity];

       for(int i = 0; i != _size; ++i)
      {
            _data[i] = x._data[i];
       }
    }

   return *this

}
Last edited on Nov 5, 2010 at 8:00pm
Topic archived. No new replies allowed.