Jump to content
  • Advertisement
Sign in to follow this  
lem

Derived template (was: this-pointer in Template)

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

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]

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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_;

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 :-)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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'......

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!