Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Overloading [] operate in a template class 1

Status
Not open for further replies.

TheInsider

Programmer
Jul 17, 2000
796
CA
Hi,

I'm new to C++ and I'm trying to overload the [] operator in a linked list template class; however, I'm getting "impossible conversion type errors". The class looks like:
Code:
template <typename T> class LinkedList
{
private:
	template <typename T> struct Node
	{
		T	*object;
		Node<T>	*next,
			*previous;
	};

	Node<T>		*head,
			*tail;
	unsigned long	size;

public:
...
	T* operator [](unsigned long index)
	{
		Node<T> *current = head;

		if (index != 0)
		{
			while ((current != NULL) && (index-- > 0))
			{
				current = current->next;
			}
		}

		return (current != NULL) ? current->object : NULL;
	}
};
Then I instantiate the list, in an "Animation" class, using another class I created called "Image". Basically, the logic is that Animation has a linked list of Image(s).
Code:
LinkedList<Image> *list;
...and then, after adding some items to the list, attempt to access the list from within the "Animation" class via the overloaded [] operator:
Code:
	Image* get_current_frame(void)
	{
		//current_index is an unsigned long private member variable
		return list[current_index];
	}
And the errors that I am receiving are:
space.cpp(279): Error! E324: col(28) conversion of return value is impossible
space.cpp(279): Note! N630: col(28) source conversion type is 'LinkedList<Image> (lvalue)'
space.cpp(279): Note! N631: col(28) target conversion type is 'Image *'

Obviously, the errors are referring to the return value of the T* operator [](unsigned long index) method.

Any help is greatly appreciated.

Thanks
 
Which compiler & version are you using?

Try compiling this program and let me know if you get the same kind of errors:
Code:
#include <iostream>

using namespace std;

template <typename T>
class Outter
{
private:
	template <typename T>
	struct Inner
	{
		T* Value;
	};

	T  m_Data;

public:
	Outter( T arg )
	:	m_Data( arg ) {};

	T* operator[]( unsigned long index )
	{
		Inner<T>* data = new Inner<T>;
		data->Value = &m_Data;

		return (index == 0) ? data->Value : NULL;
	}
};


int main()
{
	Outter<int> outter( 5 );
	cout << outter[0] << endl;

	return 0;
}
 
Hi,

Thank you for the reply. I am actually using Open Watcom v1.5 ( and the code that you provided compiles and runs without any problems. I have Visual Studio .Net, but this particular C++ compiler is better suited for the project that I am working on.
 
OK, thanks to your code, I can now see where the problem in my code is. You instantiated outter by:
Code:
Outter<int> outter( 5 );
whereas I am trying to do the following:
Code:
...
LinkedList<Image> *_frames = new LinkedList<Image>();
...
Image *image = new Image();
_frames->add(image);
...
delete _frames;
Perhaps my understanding of templates is really unclear! I thought that it was like doing the following in Java:
Code:
List<Image> list = new LinkedList();
which would enforce that only Image references can be stored in the linked list.

Can I not get a pointer to _frames? And if outter is instantiated without the new keyword... then there is no need to free or delete outter???
 
...I know that I could scrap the template <typename T> and just use void * pointers in the linked list, but then I would have to typecast everytime I retrieve an object from the list, which isn't very pretty
[morning]
 
If you want to do:
Code:
Image *image = new Image();
_frames->add(image);
you'll have to declare _frames as: LinkedList<Image*> instead of LinkedList<Image>

You'll also have to remember to delete each Image pointer that you added to your linked list before you delete the linked list.

BTW, I'm assuming you're creating your own linked list class for some school project? If not, you might want to take a look at some of the containers in the STL library like list and vector, rather than reinvent the wheel.
 
TheInsider said:
And if outter is instantiated without the new keyword... then there is no need to free or delete outter???
That's right. You only use new when you are dynamically allocating memory. If you declare a type without * or &, then it's a local variable that is created on the stack instead of the heap (i.e. it automatically gets deleted when it goes out of scope).
* is for pointers (eg. int* = new int;) and for every new there must be an equal and opposite delete, otherwise you have a memory leak.
& is for references (eg. int i = 1; int& j = i;) and they don't work quite the same as they do in Java. You can never have a NULL reference, you can never change a reference to point to something else, and you can't explicitly delete a reference.
 
Thanks, I think that clears things up. I'll also have a look at the STL library.
 
sorry if I missed the answer, but it seems you don't lack knowledge in templates, while you certainly do in pointers.

Having:
Code:
LinkedList<Image> *list;

this is an unallocated pointer (array or whatever you call it). So making

Code:
return list[n];

is considered as reference to the first element of array of type LinkedList<Image>, and not operator. So, assuming that you somewhere have that list allocated, like

Code:
list = new LinkedList<Image>;
// or
list = &some_other_list;

you do access the operator with:

Code:
return (*list)[n];

good luck.

------------------
When you do it, do it right.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top