Jump to content
  • Advertisement
Sign in to follow this  
discman1028

namespace issue

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

Hey all, I've narrowed down a compilation problem to the following case. It seems to be a namespace issue, as putting all in the global namespace fixes the problem. Any ideas? Maybe my namespace+template understanding isn't as solid as I once thought?
namespace NSbase
{
namespace NSone
{
	struct FooStruct
	{
		int a,b,c;
	};

	template <unsigned int A,unsigned int B,unsigned int C>
	FooStruct Get()
	{
		FooStruct temp = {A,B,C};
		return temp;
	}
}
}

namespace NSbase
{
namespace NStwo
{
	class CFoo
	{
	public:
		void foo( NSone::FooStruct defaultArg = NSone::Get<0,0,0>() );

	};

	void CFoo::foo( NSone::FooStruct defaultArg )
	{
	}
}
}


int main()
{
	return 0;
}


Error is:
error C2783: 'NSbase::NSone::FooStruct NSbase::NSone::Get(void)' : could not deduce template argument for 'A'
...


Share this post


Link to post
Share on other sites
Advertisement
I get errors on MinGW 4.2.1, too:


ns.cpp:26: error: expected identifier before numeric constant
ns.cpp:26: error: expected ',' or '...' before numeric constant
ns.cpp:26: error: parse error in template argument list
ns.cpp:26: error: default argument for parameter of type 'NSbase::NSone::FooStruct' has type '<unresolved overloaded fun
ction type>'
ns.cpp:26: error: default argument missing for parameter 2 of 'void NSbase::NStwo::CFoo::foo(NSbase::NSone::FooStruct, i
nt)'
ns.cpp:30: error: prototype for 'void NSbase::NStwo::CFoo::foo(NSbase::NSone::FooStruct)' does not match any in class 'N
Sbase::NStwo::CFoo'
ns.cpp:26: error: candidate is: void NSbase::NStwo::CFoo::foo(NSbase::NSone::FooStruct, int)
ns.cpp:30: warning: unused parameter 'defaultArg'
error: system call returned unexpected exit-code 1




EDIT: however, adding () around NSone::Get<0,0,0> shuts it up?!

Share this post


Link to post
Share on other sites
I believe this is a parse problem, similar to the nested template parameter parse (A<A<int>>). I'd have to dig through the standard to make sure, though. In other words, the compiler is seeing this:

void foo( FooStruct defaultArg = Get < 0, 0...

This explains the error messages; the compiler knows about Get, and thinks you're trying to compare it's addres to zero (nonsensical, of course, but the compiler's not that smart). VC++ points out that it can't determine which Get you want ("can't deduce template argument"). Did VS produce any more errors?

Either way, GCC seems to uncharacteristically produce the better diagnostic here. It tells you it expected some other identifier before what it saw as a dangling constant (the subsequent zero) - the next error message indicate it was looking for another parameter, or an ... token. A later message further suggests it has decided foo was a function taking an int, et cetera.

The parens (or wrapping the call to Get<0,0,0> in another function with no template parameters and calling that, or something) are the solution.

(FWIW, I tried it with GCC 3.4.6 and it fails. With or without namespaces.)

[Edited by - jpetrie on September 25, 2007 3:25:16 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
I believe this is a parse problem, similar to the nested template parameter parse (A<A<int>>). I'd have to dig through the standard to make sure, though. In other words, the compiler is seeing this:

void foo( FooStruct defaultArg = Get < 0, 0...



I should have mentioned that I tried lobbing in (heh, rigorous) the template keyword before "Get", but to no avail.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
Did VS produce any more errors?


No. :(

Quote:
Original post by jpetrie
The parens (or wrapping the call to Get<0,0,0> in another function with no template parameters and calling that, or something) are the solution.


That's actually what I ended up doing.

Share this post


Link to post
Share on other sites
Quote:

I should have mentioned that I tried lobbing in (heh, rigorous) the template keyword before "Get", but to no avail.

Yeah, that wouldn't be legal syntax in that context. I'm fairly sure it's just a parse deficiency that was too hard to properly implement.

Share this post


Link to post
Share on other sites
I'll note that I was able to get the compiler to shut up and do the right thing by bringing NSone::Get into NStwo's namespace, either by
using NSone::Get;

or
using namespace NSone;

and then modifying the offending line to:
void foo( NSone::FooStruct defaultArg = Get<0,0,0>() );

but of course, that is defeating the purpose of having them in separate namespaces to begin with...

Share this post


Link to post
Share on other sites
I just don't want to use "using" in the header. Otherwise I wouldn'tve minded that hack. Good tip though.

@jpetrie: Earlier, when you said it could be fixed with extra parens... how would that look?

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!