Derived template (was: this-pointer in Template)

Started by
7 comments, last by RobTheBloke 13 years, 4 months ago
I have a class, which I would like to make a template for.
The class looks like this:
class WidgetSpec{private:	typedef std::map<String, WidgetSpec*> WidgetMap;	typedef WidgetMap::iterator WidgetMapIter;};


The problem is the WidgetSpec* in the map.
How do I implement this in a template?

Doing both, gives me errors:
1.
template <class w>class Spec{private:	typedef std::map<String, this> SpecMap;	typedef SpecMap::iterator SpecMapIter;};

2.
template <class w>class Spec{private:	typedef std::map<String, Spec<w>*> SpecMap;	typedef SpecMap::iterator SpecMapIter;};


Is there a way, to solve this via templates?
Many thanks

[Edited by - lem on December 13, 2010 9:25:48 AM]
Advertisement
This should work:
template <typename W>class Spec{private:	typedef typename std::map<String, W*> SpecMap;	typedef SpecMap::iterator SpecMapIter;};

The extra typename after the typedef means the type is dependent on another type (in this case W).
Yes. Within a template declaration, if you write the "basic-name" of the template (i.e. without template arguments), it will be "converted" to the fully qualified name. E.g., if you have

template <typename T> class Foo {public:    Foo *foo;};


and then

int main () {    Foo<int> foo;}


then your foo will have a member of type "pointer to Foo<int>", i.e. the compiler will expand a

class Foo<int> {public:    Foo<int> *foo;};


for you.

Alternatively, you can type out the full template name by sourself:

template <typename T> class Foo {public:    Foo<T> *foo;};


Though this is redundant and sometimes means a lot of extra work if you extend the template argument list.


edit: I've just seen your second item and realised you are defining types, not variables. You need to use the "typename" keyword there as your typedefs use a dependent name:

typedef typename std::map<String, Spec<w>*> SpecMap;typedef std::map<String, Spec*> SpecMap_;
1 is wrong because "this" is not a type.

2, what's the error? what compiler? GCC?
then how about change
typedef std::map<String, Spec<w>*> SpecMap;
to
typedef std::map<String, Spec<typename w>*> SpecMap;
GCC requires that "typename" though I don't know if its position is correct (I didn't compile it).

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

Quote:Original post by Xycaleth
This should work:
template <typename W>class Spec{private:	typedef typename std::map<String, W*> SpecMap;	typedef SpecMap::iterator SpecMapIter;};

The extra typename after the typedef means the type is dependent on another type (in this case W).


VC is not that strict and doesn't require it. GCC does.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

Quote:Original post by wqking
Quote:Original post by Xycaleth
This should work:
template <typename W>class Spec{private:	typedef typename std::map<String, W*> SpecMap;	typedef SpecMap::iterator SpecMapIter;};

The extra typename after the typedef means the type is dependent on another type (in this case W).


VC is not that strict and doesn't require it. GCC does.


Though the OP is looking for a pointer to his class, not for a pointer to W.
Quote:Original post by wqking
2, what's the error? what compiler? GCC?

Thanks. I am using mostly GCC, but also compile on VC8.
The error is in the typedef for the iterator, that a semicolon is missing ...

I will check only the template name and then report back :-)

Ok, I am approving.

Thanks, phresnel, the typename thing did the magic ;-)

Now, I have two classes, where the first is derived from the other. Both are templates. I think, because of the static member in the base-class, I have a problem with the (double) instantiation.

This code compiles finde, but I got a runtime error, when the manager is returning the widget ...

Anyone can enlighten me on this, please?

template <class U, class T>class WidgetSpec{private:	typedef typename std::map<T, WidgetSpec*> WidgetMap;	typedef typename WidgetMap::iterator WidgetMapIter;        static U* getWidget( T );};


template <class U, class T>class WidgetManager : public WidgetSpec<U,T>{public:	WidgetManager(T type):WidgetSpec<U,T>(type) { /*foo*/ }}


Many thanks
Quote:Original post by lem
This code compiles finde, but I got a runtime error, when the manager is returning the widget ...


The lack of a return statement anywhere in your code makes it extremely difficult to suggest what the problem may be 'when the manager is returning the widget'......

This topic is closed to new replies.

Advertisement