C++ template friend class and inheritance

Started by
5 comments, last by jorgander 13 years, 7 months ago
I don't see why what I'm trying to do shouldn't be possible, but for some reason I can't get VC++ 2008 Express to like it. Here's the basic idea:

namespace Script{	template <typename T, typename GlobalTraits> class Global;	class Registry	{	private:		class GlobalInternal		{			...		};		template <typename T, typename GlobalTraits> friend Script::Global;	};	template <typename T, typename GlobalTraits>	class Global : private Registry::GlobalInternal	{		...	};}


With the above code I get this error:
1>d:\development\cpp\assware\common\include\asw\script.h(291) : error C2955: 'ASW::Script::Global' : use of class template requires template argument list1>        d:\development\cpp\assware\common\include\asw\script.h(234) : see declaration of 'ASW::Script::Global'


Does anyone know the correct syntax?

In case anyone asks, Registry::GlobalInternal is supposed to be inaccessible from any class that isn't supposed to have access to it, but still have it separate from Global so that source code that uses it can be compiled on its own (i.e. not use a template class). If anyone knows of a cleaner way to accomplish that I would like to know of it.
Advertisement
	template <typename T, typename GlobalTraits> friend class Script::Global;

Is that what you were looking for?
Quote:Original post by alvaro
	template <typename T, typename GlobalTraits> friend class Script::Global;

Is that what you were looking for?


I originally thought so, but upon adding class I am presented with this compiler error:

1>d:\development\cpp\assware\common\include\asw\script.h(315) : error C2248: 'ASW::Script::Registry::GlobalInternal' : cannot access private class declared in class 'ASW::Script::Registry'1>        d:\development\cpp\assware\common\include\asw\script.h(271) : see declaration of 'ASW::Script::Registry::GlobalInternal'1>        d:\development\cpp\assware\common\include\asw\script.h(237) : see declaration of 'ASW::Script::Registry'...


The error leads me to believe that the compiler is not matching the friend declaration with prior forward declaration, although I'm not sure of this.
Did you try:
template <typename T, typename GlobalTraits> friend class Global;

Using Script::Global is probably making the compiler think you're trying to friend ::Script::Script::Global rather than ::Script::Global.
I did try that, and I got the same error as in my second post. I also removed the forward declaration and tried it both ways - same errors.

Interestingly enough, changing the relationship from "is-a" to "has-a" compiles without error:

template <typename T, typename GlobalTraits>class Global{private:	Registry::GlobalInternal internal;	...};


Anyone know why? I would think the same access rules apply.

Perhaps it has something to do with when the compiler is loading the class - with "has-a" relationship the compiler has already read the class declaration and checked access rules, but with "is-a" it is still reading the class declaration (i.e. the class name and bases) when it encounters the base class name.
Removing the Script:: seems to work fine with inheritance with MSVC 2010. Might be time to upgrade.
Upgrading to VC++ Express 2010 does not fix it, so I'm assuming they fixed it only in the paid version. Unfortunately I'll have to go with composition for now.

This topic is closed to new replies.

Advertisement