Member data in class derived from template

M

Matthias von Faber

Hello,

The code below compiles fine on VS 6.0 and .NET 2005, but G++ complains
about mData not having been declared in the Derived class:



template<typename T>
class Base
{
public:
Base() {}
virtual ~Base() {}

protected:
int mData;
};


template<typename T>
class Derived : public Base<T>
{
public:
Derived() {}
virtual ~Derived() {}

void f()
{
mData = 0;
}
};


I have done extensive searches on the problem, including books etc., but I
have found nothing on the topic. So I am beginning to feel that I might be
fundamentally confusing something...

But then again, a Derived<T> should be a Base<T>, and those should come
with an mData member. So what could it be?

Thanks,
 
R

Rolf Magnus

Matthias said:
Hello,

The code below compiles fine on VS 6.0 and .NET 2005, but G++ complains
about mData not having been declared in the Derived class:



template<typename T>
class Base
{
public:
Base() {}
virtual ~Base() {}

protected:
int mData;
};


template<typename T>
class Derived : public Base<T>
{
public:
Derived() {}
virtual ~Derived() {}

void f()
{
mData = 0;
}
};


I have done extensive searches on the problem, including books etc., but I
have found nothing on the topic. So I am beginning to feel that I might be
fundamentally confusing something...

But then again, a Derived<T> should be a Base<T>, and those should come
with an mData member. So what could it be?

Two-phase name loopkup. The name has to be a dependant name. Since the Base
template is not instantiated at the point of Derived's definition, the
compiler doesn't know yet that mData is supposed to be a member of the
object.
Try:

void f()
{
this->mData = 0;
}
 
P

Pete Becker

Matthias said:
But then again, a Derived<T> should be a Base<T>, and those should come
with an mData member. So what could it be?

But Base<int>, for example, can be specialized, and it isn't required to
have a member named mData. So you have to tell the compiler where mData
comes from. Instead of the unadorned

mData = 0;

you can say

this->mData = 0;
Base<T>::mData = 0;

and I think there's a third one, that isn't popping into my head at the
moment.
 
A

Alf P. Steinbach

* Pete Becker:
But Base<int>, for example, can be specialized, and it isn't required to
have a member named mData. So you have to tell the compiler where mData
comes from. Instead of the unadorned

mData = 0;

you can say

this->mData = 0;
Base<T>::mData = 0;

and I think there's a third one, that isn't popping into my head at the
moment.

You're probably thinking of a using-declaration.
 
M

Matthias von Faber

this->mData = 0;

That fixed it nicely. Well, seems that I should read up on class templates
then. My conception was that all Base specializations would have an mData.

Thanks very much!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top