Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > members in class template not inherited?

Reply
Thread Tools

members in class template not inherited?

 
 
not.a@dummy.net
Guest
Posts: n/a
 
      05-19-2004
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>: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
 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      05-19-2004
wrote in news 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>: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>: += rhs.x;

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

3) use a using statement:

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

using Foo< T >:;
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.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      05-19-2004
wrote:
> 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>: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
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      05-19-2004

<> wrote in message
news. ..
> 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>: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


 
Reply With Quote
 
Siemel Naran
Guest
Posts: n/a
 
      05-20-2004
"John Harrison" <> wrote in message
> news. ..


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


> 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
instantiate a faulty Bar<T> such as Bar<int>. Or maybe I'm missing
something.

> 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>: += 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Declaring a template class with two template params a friend in anon-template class A L C++ 1 08-25-2010 07:25 AM
Template function within class template not not resolving when passedfunction local class? jrwats C++ 1 03-01-2010 08:30 AM
A parameterized class (i.e. template class / class template) is not a class? christopher diggins C++ 16 05-04-2005 12:26 AM
Can nested class members access private members of nesting class? CoolPint C++ 8 12-14-2003 02:30 PM
template members in a non-template class Nico Massi C++ 3 08-30-2003 12:57 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57