Sign in to follow this  
lem

Derived template (was: this-pointer in Template)

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
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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this