Jump to content
  • Advertisement
Sign in to follow this  
walkingcarcass

Wierd compiler error (don't worry, not much code)

This topic is 4373 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

Hi all. I've stripped down my problem code but preserved my structure, which is why the code below looks meaningless, but can someone please tell me why the commented-out line generates the GCC error expected `;' before "iter" but the corresponding line in test.cpp does not? First, PT.hpp:
namespace T {
	template<unsigned int NUM, typename DATA>
	class PT {
		int x;
		// Stuff
		
		public:
			class iterator {
				int x;
				// stuff;
			};
	};
}
and D.hpp:
#include "PT.hpp"

namespace T {
	template<typename DAT>
	class D {
		private:
			static const unsigned int NUM = 3;
			
			class DT {
				int x;
				DAT d;
				// stuff
			};

			typedef PT<NUM, DT> X;
			X x;
		//	X::iterator iter;
		// The above line gives an error.
	};
}
and test.cpp:
#include "D.hpp"

typedef T::PT<3, int> Type;

int main(){
	Type t;
	Type::iterator i; // THIS LINE COMPILES FINE
}
The files as they are above will compile, as soon as I un-comment the line in D.hpp it errors. I don't understand how they're different. (Excuse the odd names.)

Share this post


Link to post
Share on other sites
Advertisement
Google "dependant names" or "two phase lookup". Basically until the compiler knows what X is it cannot know whether X::iterator is a static data member or a nested typedef. So it assumes it's a static data member unless you use the typename keyword. To fix it just prepend the keyword typename to the statement.

The equivalent in test.cpp is not a problem because the type of Type is known.

Σnigma

Share this post


Link to post
Share on other sites
Looks like a compiler bug to me ... but to remove a very small difference can you try hard coding "3" in the template arg in the middle version to match the .cpp version? (instead of using the static const).

EDIT: Guess I was wrong.

[Edited by - Xai on May 31, 2006 8:56:52 PM]

Share this post


Link to post
Share on other sites
You have to prefix it with typename as Enigma hinted. It works with the concrete instantiation of the template because then it can just look up the name and see that it's a type, not a member.

Share this post


Link to post
Share on other sites
Okay, changing X::iterator iter; to typename X::iterator iter; works fine, thanks a lot, but I still don't understand the problem. Google is giving me far too in-depth results that can only be understood with a familiar copy of the language in-hand.

I thought I'd removed any ambiguity with typedef PT<NUM, DT> X; since there is no X defined anywhere else. I fail to see how adding "typename" gives the compiler any clue at all.

Share this post


Link to post
Share on other sites
Essentially, the compiler needs to know if X::iterator refers to a type or to a variable before it instantiates the template class. It assumes it refers to a variable unless you use the typename keyword.

Share this post


Link to post
Share on other sites
The problem is that X is a type than depends on template parameters, so the meaning of X::iterator could be different depending on what the template parameters are. Is X::iterator another type, or is it a static data member? If the compiler doesn't know, it assume it is a static data member. The problem is not with X itself, but with iterator in X.

To tell the compiler that X::iterator is a type, you add the typename keyword.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!