members in class template not inherited?

N

not.a

When I compile the following code:

//===================================================
template <typename T>
class Foo {
public:
T x,y,z;
};

template <typename T>
class Bar : public Foo<T> {
public:
Bar<T>& operator+=(const Bar<T>& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;

return *this;
}
};
//===================================================

I get the following message from gcc 3.4:

bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
bad.cpp:11: error: `x' undeclared (first use this function)
bad.cpp:11: error: (Each undeclared identifier is reported only once for
each function it appears in.)
bad.cpp:12: error: `y' undeclared (first use this function)
bad.cpp:13: error: `z' undeclared (first use this function)

If I "un-templatize" the classes Foo and Bar, the code compiles fine. Is
this a bug in gcc, or am I forgetting something about the way C++ handles
inheritance and templates?

Thanks,

Brett
 
R

Rob Williscroft

wrote in in
comp.lang.c++:
When I compile the following code:

//===================================================
template <typename T>
class Foo {
public:
T x,y,z;
};

template <typename T>
class Bar : public Foo<T> {
public:
Bar<T>& operator+=(const Bar<T>& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;

return *this;
}
};
//===================================================

I get the following message from gcc 3.4:

bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const
Bar<T>&)': bad.cpp:11: error: `x' undeclared (first use this function)
bad.cpp:11: error: (Each undeclared identifier is reported only once
for each function it appears in.)
bad.cpp:12: error: `y' undeclared (first use this function)
bad.cpp:13: error: `z' undeclared (first use this function)

If I "un-templatize" the classes Foo and Bar, the code compiles fine.
Is this a bug in gcc, or am I forgetting something about the way C++
handles inheritance and templates?

It is not inheritance and templates, it si names that *depend* on a
template paramiter, because of specialization, whatever Foo< T > is
*depends* on T, so the compiler can't assume that Foo< T > is the
un-specialized version its already seen, so it can't assume x, y
and z are members of Foo< T >.

Ehat to do:

1) use this->x etc.

2) use explicit qualification:

Foo<T>::x += rhs.x;

Note that rhs.Foo<T>::x isn't required as its effectively (1).

3) use a using statement:

template <typename T>
class Bar : public Foo<T> {
public:

using Foo< T >::x;
using Foo< T >::y;
using Foo< T >::z;


Bar<T>& operator+=(const Bar<T>& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;

return *this;
}
};

HTH.

Rob.
 
V

Victor Bazarov

When I compile the following code:

//===================================================
template <typename T>
class Foo {
public:
T x,y,z;
};

template <typename T>
class Bar : public Foo<T> {
public:
Bar<T>& operator+=(const Bar<T>& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;

return *this;
}
};
//===================================================

I get the following message from gcc 3.4:

bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
bad.cpp:11: error: `x' undeclared (first use this function)
bad.cpp:11: error: (Each undeclared identifier is reported only once
for each function it appears in.)
bad.cpp:12: error: `y' undeclared (first use this function)
bad.cpp:13: error: `z' undeclared (first use this function)

If I "un-templatize" the classes Foo and Bar, the code compiles fine.
Is this a bug in gcc, or am I forgetting something about the way C++
handles inheritance and templates?

I think the problem is in name lookup rules. I am too lazy and too busy
to search through the Standard at this point, but try this fix:

Bar<T>& operator+=(const Bar<T>& rhs) {
this->x += rhs.x;
this->y += rhs.y;
this->z += rhs.z;

return *this;
}

Victor
 
J

John Harrison

When I compile the following code:

//===================================================
template <typename T>
class Foo {
public:
T x,y,z;
};

template <typename T>
class Bar : public Foo<T> {
public:
Bar<T>& operator+=(const Bar<T>& rhs) {
x += rhs.x;
y += rhs.y;
z += rhs.z;

return *this;
}
};
//===================================================

I get the following message from gcc 3.4:

bad.cpp: In member function `Bar<T>& Bar<T>::eek:perator+=(const Bar<T>&)':
bad.cpp:11: error: `x' undeclared (first use this function)
bad.cpp:11: error: (Each undeclared identifier is reported only once for
each function it appears in.)
bad.cpp:12: error: `y' undeclared (first use this function)
bad.cpp:13: error: `z' undeclared (first use this function)

If I "un-templatize" the classes Foo and Bar, the code compiles fine. Is
this a bug in gcc, or am I forgetting something about the way C++ handles
inheritance and templates?

The latter. This is known as dependent name lookup.

From the standard 'In the definition of a class template ..., if the base
class of the class template depends upon a template parameter, the base
clsas scope is not examined during unqualified name lookup'. (section 14.6.2
para 3)

Why? I'm not sure. I'm sure there is a good reason.

The solution is to turn your unqualifed names into qualified names by
putting this-> in front of them.

this->x += rhs.x;

john
 
S

Siemel Naran

From the standard 'In the definition of a class template ..., if the base
class of the class template depends upon a template parameter, the base
clsas scope is not examined during unqualified name lookup'. (section 14.6.2
para 3)

Why? I'm not sure. I'm sure there is a good reason.

The reason I was given is that Foo<T> may be specialized so that it
does not have members 'x', 'y', and/or 'z'. It does not seem very
convicing to me, because the errors could spew forth when we finally
The solution is to turn your unqualifed names into qualified names by
putting this-> in front of them.

this->x += rhs.x;

One can also say

Foo<T>::x += rhs.x;

For functions this could be dangerous as it turns off the virtual
function mechanism (ie. functions will be resolved statically). But I
prefer the "this->" way of doing it.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top