Jump to content
  • Advertisement
Sign in to follow this  
Taldor

Temlpate instantiation problem (part 2)

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

<edit> My first problem is solved. For my second problem, see below. </edit> The problem is explained in the code:
class One {};
class Two : virtual public One {};

template <class T> class Three : public Two
{
	public :
		Three () {};
		template <class U> Three (const Three <U> & other) {};
};

class A {};
template <class T> class B : public A {};

class X {};

template class B <X>;

template class Three <A>;
template class Three <B <X> >;

//	This line gives a 'template-id ... does not match any template declaration' error.
//	(This would work if 'Two' wouldn't inherit 'One' virtual.)
//	template Three <A> :: Three (const Three <B <X> > & other);

//	Someone on the GameDev.net IRC channel suggested this solution,
//	but it only seems to work for non-template classes (like A).
//	Here I get a '... is not a valid type for a template constant parameter' error.
template <class A>
	template <class B <X> > /* Here's the problem. */
	Three <A> :: Three (const Three <B <X> > & other);

int main ()
{
	Three <B <X> > B3;
	Three <A> A3 (B3);

	return 0;
}




[Edited by - Taldor on October 28, 2007 2:41:31 PM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by ToohrVyk
template <class A>
template <class B>
Three <A> :: Three (const Three <B> & other);
?

Okay, that works. :-) I thought that the argument type had to be a fully defined class, but apparently that's incorrect. Thanks!

Now a similar problem with templates & namespaces...

abc.hpp:

class One {};
class Two : virtual public One {};

template <class T> class Three :
public Two
{
public :
Three () {};
template <class U> Three (const Three <U> & other);
};






abc.cpp:

#include "abc.hpp"

namespace XX
{
class X {};
}
namespace YY
{
class Y {};
}

namespace AA
{
template <class T> class A {};
}
namespace BB
{
template <class T> class B : public AA :: A <XX :: X> {};
}

template class AA :: A <XX :: X>;
template class BB :: B <YY :: Y>;

template class Three <AA :: A <XX :: X> >;
template class Three <BB :: B <YY :: Y> >;


// This gives errors:
// 'invalid use of template-name ... without an argument list'
template <class AA :: A>
template <class BB :: B>
Three <AA :: A> :: Three (const Three <BB :: B> & other);

int main ()
{
Three <BB :: B <XX :: X> > B3;
Three <AA :: A <YY :: Y> > A3 (B3);

return 0;
}






What should I do here?

[Edited by - Taldor on October 28, 2007 2:19:04 PM]

Share this post


Link to post
Share on other sites
template <class SomeCompletelyIrrelevantName>
template <class AnotherCompletelyIrrelevantName>
Three <SomeCompletelyIrrelevantName> :: Three (
const Three <AnotherCompletelyIrrelevantName> & other);

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
template <class SomeCompletelyIrrelevantName>
template <class AnotherCompletelyIrrelevantName>
Three <SomeCompletelyIrrelevantName> :: Three (
const Three <AnotherCompletelyIrrelevantName> & other);

No, the names are relevant, otherwise I end up with linking errors. Here's explained why I do this.

Share this post


Link to post
Share on other sites
Quote:
Original post by Taldor
No, the names are relevant, otherwise I end up with linking errors. Here's explained why I do this.


They are irrelevant, in that the compiler will simply ignore them—they're template parameters, not template arguments, and as such their name has no impact on the code beyond the obvious search-and-replace effect that occurs when an argument is provided for a parameter.

Of course, if you're trying to manually instantiate your templates by hand, then the entire template<class FooBar> contraption is useless (as it forward-declares a template without instantiating it) independently of your template arguments being templates or your namespace issues.

In the end, I'm afraid I have no clue about why introducing virtual inheritance eliminates that template constructor. The closest I could get was:
template<class C1,class C2>
void convert(const C2 & o)
{
return (void) C1(o);
}

template convert< Three<A>, Three< B<X> > >
convert(const Three< B<X> > &)


Which should force the instantiation of the adapted constructor.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
template<class C1,class C2>
void convert(const C2 & o)
{
return (void) C1(o);
}

template convert< Three<A>, Three< B<X> > >
convert(const Three< B<X> > &)



Sadly, this only works in this example and not in my actual code. ('One' corresponds to 'boost :: noncopyable', 'Two' to 'Reference_Base' and 'Three' to 'Reference'. I'd like to make 'Reference_Base' inheriting virtual from 'boost :: noncopyable', but I didn't upload it as such yet, because of this problem.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Taldor
Sadly, this only works in this example and not in my actual code.


Erm. You're much more familiar with your own code than I am, so could you please say what the exact problem is in adapting this example to your code? The way I see it, you merely have to define a function which calls the appropriate constructor (something which should be possible if you ever intended to call that constructor in the first place);

Share this post


Link to post
Share on other sites
Any constructor declared in the child will prevent the compiler from even attempting to match against this template in the parent. I have no idea if this is relevant, but someone mentioned constructors.

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!