Jump to content
  • Advertisement
Sign in to follow this  
cmptrgear

declare template member of template class

This topic is 4366 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I dont do a whole lot of template programming for my job so I am not sure if I am trying to do something that is not allowed or if I just have the syntax wrong. What I am trying to do is have a template class with a std::vector as a private member. Here is some example code.
template <class T> class Base
{
private:
   std::vector<T *> list;
   std::vector<T *>::iterator listIter;
public:
   Base();
   virtual ~Base();
};



When I compile my code that uses this class I get this error: error: expected ";" before listIter If I change the code to this std::vector<T *> list; std::vector<int *>::iterator listIter; The code compiles but obviously wont work since the iterator is not the same type as list. It seems that it is alright to declare a vector in this manner but it is not ok to declare an iterator in this manner. Is it possible to do this or do I need to come up with a different design? EDIT: I just tried doing this in VS 2005 and XCode 2.2 and they both give the same error, so I guess for whatever reason I am not allowed to declare an iterator without a defined type.

Share this post


Link to post
Share on other sites
Advertisement
Try:
typename std::vector<T *>::iterator listIter;
This will clarify to the compiler that 'iterator' is a type rather than a static member variable or enumerated value.

(That explanation may not be complete or completely accurate. Someone posted a link to a more in-depth explanation here a while ago, but I don't have it handy.)

Share this post


Link to post
Share on other sites
Put 'typename' before your iterator declaration. Because of the T, typename is needed to let the compiler know that ::iterator is definately a type and not a variable.

CM

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Try:
typename std::vector<T *>::iterator listIter;
This will clarify to the compiler that 'iterator' is a type rather than a static member variable or enumerated value.

(That explanation may not be complete or completely accurate. Someone posted a link to a more in-depth explanation here a while ago, but I don't have it handy.)


Thanks that seems to have gotten rid of the compiler errors. I dont think I have ever come across the typename keyword before. I will have to look it up when I get a chance.

Share this post


Link to post
Share on other sites
Quote:
Original post by cmptrgear
Quote:
Original post by jyk
Try:
typename std::vector<T *>::iterator listIter;
This will clarify to the compiler that 'iterator' is a type rather than a static member variable or enumerated value.

(That explanation may not be complete or completely accurate. Someone posted a link to a more in-depth explanation here a while ago, but I don't have it handy.)


Thanks that seems to have gotten rid of the compiler errors. I dont think I have ever come across the typename keyword before. I will have to look it up when I get a chance.

Its relatively obscure, because until recently compilers let you ignore it in most situations. More and more template articles will probably cover it now that g++ and VC++ both have stopped ignoring it.

CM

Share this post


Link to post
Share on other sites
The trick is, at the time the compiler reads the statement, it can't know that, for all T, 'std::vector<T*>::iterator' is a typename. There could be a specialization of std::vector somewhere:


// Not sure, but something like this:
class Evil {};

template<>
class std::vector<Evil> {
int iterator;
// everything else copied from the default implementation
};


If you didn't have to use the typename keyword, then this error couldn't be caught until much later in the process, and you'd get a really horrible error message from it (or maybe even an ICE). With 'typename', the compiler says "I know this has to be a typename", so when it tries to instantiate Base<Evil>, it has additional information such that it can see the problem right away.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!