Archived

This topic is now archived and is closed to further replies.

gimp

Advanced template syntax question(embedding)

Recommended Posts

I''d like to embed one template within another but cannot work out the syntax for the implementation. For example the real code:
  
template <typename T>
class CFactory
{
public:

	template <typename D>
	class CMaker : public CMakerBase
	{
	public:
		CMaker(const std::string& a_Name)
		{
			CFactory<T>::GetInstance().Register(a_Name, this);
		}

	}
}
//This currently works, however as a standard all my implementation code is in a seperate file (included). This where I get stuck. Here is my incorrect attempt to move the CMaker constuctor out of the interface:


template <typename T>
inline CFactory<T>::CMaker::CMaker(const std::string& a_Name)
{
	CFactory<T>::GetInstance().Register(a_Name, this);
}
  
Can anyone see where I''ve gone wrong? Many thanks for any help you can offer. Chris Brodie http:\\fourth.flipcode.com

Share this post


Link to post
Share on other sites
How about trying:

template <typename T, typename D>
inline CFactory<T>::CMaker<D>::CMaker(const std::string& a_Name)

I'm purely speculating though... I've never tried something like that.

Edited by - Kylotan on June 12, 2001 10:49:04 PM

Share this post


Link to post
Share on other sites
That''s the sort of template stuff that MSVC is really bad at - and the kind of code that makes it crash on my computer ;(


Actually I recall a post like this a short while ago - you can nest template classes but you must define the nested class'' methods inline

Magmai Kai Holmlor
- The disgruntled & disillusioned

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
As per the C++ standard, section 14.5.2, you would declare CMaker''s constructor as:

  
template <typename T> template <typename D>
inline CFactory<T>::CMaker<D>::CMaker(const std::string& a_Name)
{
CFactory<T>::GetInstance().Register(a_Name, this);
}


My main point, taken from the standard, is that you don''t combine the template specifications, you simply list them in order. As for the rest of the function, I''ve not checked its correctness, although I do think the <D> goes with the first ''CMaker'' (the type) rather than the second (the function).

Share this post


Link to post
Share on other sites
Thanks guys,

The problem persists however.

Kylotan, Your solution compiled but for some reason the linker gave me a unresolved external.... I compared the linker output to the source and it seems to be close enough...

Magmai, thanks. I currently do have it working that way. I guess as usual in my code I''m being obtuse and trying to make everything ''standard''.

Anon, thanks for the effort. Sooner or later I''ll go looking for ''the standard'' so i can look these things up myself. I had a problem with your code however. It didn''t compile:

c:\program files\microsoft visual studio\myprojects\xml\factory.inl(74) : error C2059: syntax error : ''''template<''''
c:\program files\microsoft visual studio\myprojects\xml\factory.inl(75) : error C2065: ''D'' : undeclared identifier
c:\program files\microsoft visual studio\vc98\include\vector(17) : error C2143: syntax error : missing '';'' before ''{''
c:\program files\microsoft visual studio\vc98\include\vector(17) : error C2447: missing function header (old-style formal list?)
c:\program files\microsoft visual studio\myprojects\xml\xmlstream.inl(14) : error C2039: ''__ctor'' : is not a member of ''CXMLStream''
c:\program files\microsoft visual studio\myprojects\xml\xmlstream.h(40) : see declaration of ''CXMLStream''
...snip...

Any thoughts?

Thanks

Chris

Chris Brodie
http:\\fourth.flipcode.com

Share this post


Link to post
Share on other sites
I think the correct syntax would be:

  
template <typename T, typename D>
inline CFactory<T>::CMaker<D>::CMaker(const std::string& a_Name)
{
CFactory<T>::GetInstance().Register(a_Name, this);
}


But again, it doesn''t work in MSVC.

Magmai Kai Holmlor
- The disgruntled & disillusioned

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I''ll state AGAIN that when you have a template member inside a template class you DO NOT combine the template specifications. It will never link, if it even compiles.

Don''t be fooled if your compiler issues no warnings. With templates, if it''s never actually used, only it''s syntax is checked, and there may not be problems with that. But you''ll hit a link error and wonder what the hell''s going on.

The correct way, as per the standard, and as I mentioned above, is to do:

  
template <typename T> template <typename D>
yadda yadda yadda rest of stuff goes here


Only like this, when all is said and done, can things be linked properly.

Please note that MSVC is a VERY POOR example of a C++ compliant compiler. It has so many holes you could strain pasta with it. Template handling is especially one of MSVC''s weak points.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Oh, another thing... It''s often much easier simply to put all your templatized code such as this into the header. While it seems "wrong", it''s not that bad.

The alternative -- putting it into a .cpp file -- has the advantage of separation, but the disadvantage of manually maintaining a list of the types used with it. For example, look at this:

  
//stack.h

template <typename T>
class Stack {
void foo();
};

//stack.cpp

include <stack.h>

template <typename T>
void Stack<T>::foo()
{
//whatever....

}

template Stack<int>;
template Stack<float>;


Those last two lines (see standard sec 14.7.2) tell the compiler that you''ll need a Stack of ints and a Stack of floats. If you need more versions, you have to keep track of them in that file.

Why? When the compiler attempts to build stack.cpp, it firsts checks the syntax. Then it tries to determine the usage. If those last lines are not there, the compiler decides that the template is not used, so it generates no code. Other files may include stack.h and declare various templated stacks, but because that information is not known when building stack.cpp, you will get linking errors.

That is most likely part of your problem, if you are missing such declarations. It''s also why many programmers leave template code in headers... it''s a bit of an annoyance, but less to maintain.

I still assert that template template is the correct way as well (rather than template ) although I hardly expect Microsoft to get things right.

Share this post


Link to post
Share on other sites