std::vector and template problem...

Started by
16 comments, last by Oxyd 15 years, 11 months ago
Hi, I'm curious why the following doesn't work.

template <class T>      //do I need to define T somewhere?
class ResourceManager
{
    private:
        vector<T*> *items;

    public:
    
    void init()
    {
        items = new vector<T*>;

        for (vector<T*>::iterator i = items->begin(); i != items->end(); i++) //<-- This is not accepted, "Expected ; before i" 
        {
          //...  do stuff
        }
    }
}

To me it should work, but this is my first attempt using templates, so I might be missing something. I also have the same problem with std::map. Thanks for your time! /Robert
"Game Maker For Life, probably never professional thou." =)
Advertisement
You should be more specific than just saying "it doesnt work"... [EDIT] - ahh, I see you described the error in your comments, never mind!

Anyway, you need a semicolon on the end of your class definition, and you need "std::" in front of "vector". This works for me:
template <class T>class ResourceManager{    private:        std::vector<T*> *items;    public:        void init()    {        items = new std::vector<T*>;        for (std::vector<T*>::iterator i = items->begin(); i != items->end(); i++)        {          //...  do stuff        }    }};


[EDIT]
As for style:

1) Dont use init functions! Use constructors and destructors:
template <class T>class ResourceManager{private:	std::vector<T*> *items;public:	ResourceManager()	{		items = new std::vector<T*>;		for (std::vector<T*>::iterator i = items->begin(); i != items->end(); i++)		{			//...  do stuff		}	}	~ResourceManager()	{		delete items;	}};


2) Is there any reason that items is a pointer?:
template <class T>class ResourceManager{private:	std::vector<T*> items;public:	ResourceManager()	{		for (std::vector<T*>::iterator i = items.begin(); i != items.end(); i++)		{			//...  do stuff		}	}};
You're probably missing a typename keyword
typename vector<T*>::iterator
The compiler is not certain that std::vector<T*>::iterator is actually referring to a type in this case — as far as it's concerned, it has as much chance of being a type as it does a member.

Just give it a hint that it's a type:

for ( typename std::vector< T* >::iterator i = ... )
Quote:Original post by SiCrane
You're probably missing a typename keyword
typename vector<T*>::iterator


Serves me right for wandering away before posting.
Hi!

"typename vector<T*>::iterator" did the trick!

I just noticed that I've left out quite a bit of information, for instance:
In my code I do have a semicolon after the class declaration, and "using namespace std". I also create and delete "items" in the constructor/destructor.
I guess I shouldn't post before going to sleep! :)

Also, about "items" being a pointer - I've read somewhere that the memory used when dynamically allocating variables is faster than putting it on the stack, so that's why. :)

Much appreciated, thanks again!

/Robert
"Game Maker For Life, probably never professional thou." =)
Quote:Original post by Rasmadrak

Also, about "items" being a pointer - I've read somewhere that the memory used when dynamically allocating variables is faster than putting it on the stack, so that's why. :)

It's the contrary : putting/removing variables on the stack is faster that allocating/deallocating memory for them on the heap, unless you've written a damned good allocator for your types.
English is not my native language.Sam.
Quote:Original post by rolkA
Quote:Original post by Rasmadrak

Also, about "items" being a pointer - I've read somewhere that the memory used when dynamically allocating variables is faster than putting it on the stack, so that's why. :)

It's the contrary : putting/removing variables on the stack is faster that allocating/deallocating memory for them on the heap, unless you've written a damned good allocator for your types.


And, regardless, std::vector stores elements dynamically, anyway, so why not just let it serve the purpose it's meant to (i.e. be a resizeable array that looks after its own memory) rather than abusing it?
[TheUnbeliever]
Quote:Original post by TheUnbeliever
Quote:Original post by rolkA
Quote:Original post by Rasmadrak

Also, about "items" being a pointer - I've read somewhere that the memory used when dynamically allocating variables is faster than putting it on the stack, so that's why. :)

It's the contrary : putting/removing variables on the stack is faster that allocating/deallocating memory for them on the heap, unless you've written a damned good allocator for your types.


And, regardless, std::vector stores elements dynamically, anyway, so why not just let it serve the purpose it's meant to (i.e. be a resizeable array that looks after its own memory) rather than abusing it?


And, regardless that, the std::vector object will not necessarily be on the stack — it will be in the same storage as the enclosing ResourceManager-type object (i.e., if you do new ResourceManager then the vector will be allocated in the free store even without newing it manually).

Furthermore, and most importantly — you wouldn’t notice the difference anyway. Unless your algorithm were terribly wrong — in which case your performance bottleneck would be the algorithm and not your allocation method. So, to reiterate the Golden Rule — do not optimise prematurely.
Quote:Original post by SiCrane
You're probably missing a typename keyword
typename vector<T*>::iterator


Could someone explain why this needs to be typename'd? I'm not completely familiar with typenames, and I would have written this same for loop (without a typename) and would have had the same problem. Why doesn't that work just as an iterator for the for loop?

This topic is closed to new replies.

Advertisement