|
View:
New views
5 Messages
—
Rating Filter:
Alert me
|
|
|
Referring to a base class with template template parametersI'm having issues referring to a base class under specific circumstances, and am hoping that someone can provide a work-around.
I have a base class A with a template template parameter T: template <template <typename> class T> class A { public: A(int) {} }; I then have a templated child class that derives from A using CRTP: template <typename> class B : public A { public: B(int i) : A(i) {} }; gcc reports the following error on the line with B's constructor initializer list: "error: expected a class template, got 'B< <template-parameter-1-1> > I can accomplish this in Visual Studio, but I can't find the syntax to make it work in gcc v4.2.1 It seems to be a specific issue with referring to A inside the definition of B. Note that the following DOES compile template <typename> class Foo { }; template <typename> class B : public A<Foo> { public: B(int i) : A<Foo>(i) {} Is there some obscure syntax I can use to get around this? Thanks for your help! -Alex |
|
|
Re: Referring to a base class with template template parametersDeth <alexrepair@...> writes:
> I'm having issues referring to a base class under specific circumstances, and > am hoping that someone can provide a work-around. > > I have a base class A with a template template parameter T: > > template <template <typename> class T> > class A { > public: > A(int) {} > }; > > I then have a templated child class that derives from A using CRTP: > > template <typename> > class B : public A { > public: > B(int i) > : A(i) {} > }; > > gcc reports the following error on the line with B's constructor initializer > list: > "error: expected a class template, got 'B< <template-parameter-1-1> > > > I can accomplish this in Visual Studio, but I can't find the syntax to make > it work in gcc v4.2.1 I don't know why your code would work in Visual Studio. To me it looks wrong in several places. This code works in gcc, and I believe is standard conformant. template <typename T> class A { public: A(int) {} }; template <typename T> class B : public A<B<T> > { public: B(int i) : A<B<T> >(i) {} }; Ian |
|
|
Re: Referring to a base class with template template parameters*EDIT* Bah - of course, <B> bolds text, so the code in my two posts didn't show up right. Hopefully this works better:
Thanks Ian, but my code is definitely correct - lookup "template template" parameters if you're not familiar with the syntax in my post. Your code is different because B<T> is a final type (not sure if that's the correct term). In my example, class A can create a different template instantiation of B because B is declared as a 'template template' parameter. This code without inheritance illustrates the problem a little clearer: //template template syntax is required to allow A::makeAnIntC() to //return a new template instantiation of C template <template <typename> class C> class A { C<int> makeAnIntC() {return C<int>(5);} }; template <typename T> class Bee { public: Bee(T) {} Bee<int> makeAnIntB() {return A<Bee>::makeAnIntC();} //Compile error here }; Note that the following will compile and work: class Foo { Bee<int> makeAnIntB() {return A<Bee>::makeAnIntC();} //Not self-referential }; I found the following workarounds that at least get it to compile: 1.) Create a typedef outside of Bee: template <typename> class Bee; //forward declare Bee typedef A<Bee> AB; Bee can then call: return AB::makeAnIntC(); 2.) This doesn't work if the type of A depends on a template parameter of Bee. In that case, I found I could use an indirection class to declare the type: //Class A now depends on another type (specified by Bee) template <typename T, template <typename> class C> class A; template <typename> class B; //forward declare Bee template <typename T> class Typer { typedef A<T,Bee> Type; } Bee can then call: typedef typename Typer<T>::Type AB; return AB::makeAnIntC Definitely not ideal, but it skirts around the problem for now. This seems like a compiler bug to me - can anyone shed some insight? Thanks, -aG
|
|
|
Re: Referring to a base class with template template parametersDeth <alexrepair@...> writes:
> Thanks Ian, but my code is definitely correct - lookup "template template" > parameters if you're not familiar with the syntax in my post. You're right, I misunderstood what you wanted to do, but I'm not convinced your code is correct according to the standard. Your original example said template <typename> class B : public A { so it didn't provide any type for A's template parameter. Shouldn't it be template <typename> class B : public A<B> { ? Otherwise, how does the compiler know what to use for A's template parameter? The problem then boils down to: how do you write the constructor B(int i) : A<...>(i) {} The problem is that when you write B(int i) : A<B>(i) {} B refers to the instantiated class B<>, not the template B. So you need to qualify it. Is this code what you are after? template <template <typename> class T> class A { public: A(int) {} }; template <typename> class B : public A<B> { public: B(int i) : A< ::B>(i) {} }; (note the space required between "<" and "::" to avoid a digraph). > This code without inheritance illustrates the problem a little clearer: > > //template template syntax is required to allow A::makeAnIntC() to > //return a new template instantiation of C > template <template <typename> class C> > class A { > C<int> makeAnIntC() {return C<int>(5);} > }; > > template <typename T> > class B { > public: > B<int> makeAnIntB() {return A::makeAnIntC();} //Compile error here > }; You're using A with no template parameter, and that is precisely what the compiler complains about. > Note that the following will compile and work: > class Foo { > B<int> makeAnIntB() {return A::makeAnIntC();} //Not self-referential > }; I see an error with this version as well. foo.cc:15: error: ‘template<template<class> class C> class A’ used without template parameters Ian |
|
|
Re: Referring to a base class with template template parametersPerfect! That's exactly what I was looking for. All of my "<B>" text was turned into HTML bold tags, so the code in my original post (and the pre-edit follow-up) was garbage. Sorry for the confusion!
-Alex
|
| Free embeddable forum powered by Nabble | Forum Help |