Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Templates and accessing inherited members

Reply
Thread Tools

Templates and accessing inherited members

 
 
Simon White
Guest
Posts: n/a
 
      06-16-2004
Hi,

I have code that looks legal to me and has compiled for years and on
latest VC, etc compilers. Just recently gcc made a change to their
compiler (3.4) that broke it. I don't have access to the C++ standard
but information we do have access to uptill now suggests that this
shouldn't be a problem. A code example is this:

template<class T>
class Base
{
protected:
T* a;
};

template<class T>
class Child: public Base<T>
{
public:
Child() { a = 0; }
};

When compiled gcc 3.4 now complains that "a" is undefined as it nolonger
looks to the base class(es). By default it now looks only to its own
class scope or global scope. It now means you have to add either "using
Base<T> a" to the child class or change occurances to use this->a.

Is this behaviour correct and just wondered what reasoning there was
behind it, especially when making the behaviour inconsistant after so
long with normal structs and classes, requring large amounts of code rework?

Regards,
Simon
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      06-16-2004

"Simon White" <(E-Mail Removed)> wrote in message
news:RGSzc.11$(E-Mail Removed)...
> Hi,
>
> I have code that looks legal to me and has compiled for years and on
> latest VC, etc compilers. Just recently gcc made a change to their
> compiler (3.4) that broke it. I don't have access to the C++ standard
> but information we do have access to uptill now suggests that this
> shouldn't be a problem. A code example is this:
>
> template<class T>
> class Base
> {
> protected:
> T* a;
> };
>
> template<class T>
> class Child: public Base<T>
> {
> public:
> Child() { a = 0; }
> };
>
> When compiled gcc 3.4 now complains that "a" is undefined as it nolonger
> looks to the base class(es). By default it now looks only to its own
> class scope or global scope. It now means you have to add either "using
> Base<T> a" to the child class or change occurances to use this->a.
>
> Is this behaviour correct and just wondered what reasoning there was
> behind it, especially when making the behaviour inconsistant after so
> long with normal structs and classes, requring large amounts of code

rework?
>


Its correct, its called two phase lookup.

The heart of the issue is that templates cannot be treated the same as
normal structs and classes, because of the way the types of template
parameters are not known when templates are first compiled, only when they
are instantiated. Take your example

template<class T>
class Base
{
protected:
T* a;
};

template<class T>
class Child: public Base<T>
{
public:
Child() { a = 0; }
};

Now you might think that it obvious that the a in Child::Child() must refer
to Base::a but this isn't true at all. Suppose else where in your code you
had this

extern int a;

template <>
class Base<int>
{
};

int f()
{
Child<int> x;
}

Base has been specialised with an int template parameter. The specialised
version of Base does not have a member variable called a, but there is a
global variable called a. In this code the a in Child::Child() would refer
to the global variable a, so it is wrong for previous versions of gcc to
assume that the a in Child::Child() refers to Base::a. And of course the
compiler cannot (in general) know of the existence of this specialised
version of Base when it is compiling Child.

john


 
Reply With Quote
 
 
 
 
Sharad Kala
Guest
Posts: n/a
 
      06-16-2004

"Simon White" <(E-Mail Removed)> wrote in message
news:RGSzc.11$(E-Mail Removed)...
> Hi,
>
> I have code that looks legal to me and has compiled for years and on
> latest VC, etc compilers. Just recently gcc made a change to their
> compiler (3.4) that broke it. I don't have access to the C++ standard
> but information we do have access to uptill now suggests that this
> shouldn't be a problem. A code example is this:
>
> template<class T>
> class Base
> {
> protected:
> T* a;
> };
>
> template<class T>
> class Child: public Base<T>
> {
> public:
> Child() { a = 0; }
> };
>
> When compiled gcc 3.4 now complains that "a" is undefined as it nolonger
> looks to the base class(es). By default it now looks only to its own
> class scope or global scope. It now means you have to add either "using
> Base<T> a" to the child class or change occurances to use this->a.
>
> Is this behaviour correct and just wondered what reasoning there was
> behind it, especially when making the behaviour inconsistant after so
> long with normal structs and classes, requring large amounts of code rework?


Two phase name lookup strikes again!
Since the name a is not dependent it will be looked up at the point where
template is defined w/o taking into account the instantiation type(and not when
being instantiated). Hence the error.
Base<T>::a or this->a makes it a dependent name and hence name lookup is
delayed.

-Sharad




 
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
Which members are created automatically, which members are not inherited? lovecreatesbeauty C Programming 43 02-06-2006 11:36 PM
Which members are created automatically, which members are not inherited? lovecreatesbeauty C++ 2 01-26-2006 06:03 PM
nested classes accessing inherited protected members of parents Mr Dyl C++ 2 12-01-2005 03:41 PM
Templates: Members Vs. non-members Dave C++ 3 08-10-2004 11:23 AM
Templates templates templates JKop C++ 3 07-21-2004 11:44 AM



Advertisments