help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with g++ 4.0.2 (templates, friends and inheritance)


From: Thomas Maeder
Subject: Re: Problems with g++ 4.0.2 (templates, friends and inheritance)
Date: Fri, 02 Dec 2005 18:45:13 +0100
User-agent: Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.4 (Jumbo Shrimp, linux)

Emanuel Ziegler <eziegler@web.de> writes:

> template <class T>
> class FriendClass
> {
>   // This line causes trouble
>   friend T get_test<T> (const FriendClass &);
>   protected:
>     T test;
> };
>
> template <class T>
> T get_test (const FriendClass<T> &fc)
> {
>   return fc.test;
> }
>
> int main ()
> {
>   FriendClass<int> fc;
>   get_test(fc);
>   return 0;
> }
>
> --->8---
>
> compiled without any problems before, it now gives the errors
>   error: 'get_test' is neither function nor member function; cannot
>   be declared friend
>   error: expected ';' before '<' token
> in 4.0.2. But I'm pretty sure it's valid C++ code.

I'm pretty sure it isn't.

Declare get_test before FriendClass and you should be fine:

template <class T>
class FriendClass;

template <class T>
T get_test (const FriendClass<T> &);

template <class T>
class FriendClass
{
  // This line causes trouble
  friend T get_test<> (const FriendClass &);

...


> Another problem concerns inheritance. Although members are declared
> protected and inheritance is public, the members are not transferred
> into the scope of the derived class:
>
> ---8<---
>
> template <class T>
> class Base
> {
>   protected:
>     int test;
> };
>
> template <class T>
> class Derived : public Base<T>
> {
>   protected:
>     // This doesn't work
>     /* using namespace Base<T>; */
>     // This works but should be useless and is unhandy
>     using Base<T>::test;

Indeed.


>     void set_test ()
>     {
>       test = 0;

The compiler is correct again.

For some T's, there might be a specialization for Base<T> that doesn't
declare a member test. The (apparent) Base class template is therefore
not considered when the name test is looked up.


If you write

        this->test = 0;

, test becomes a dependant name, which causes its lookup to be defered
to instantiation time. At that time, the inherited test will be taken
into consideration.


> Anyone else experienced similar problems?

Certainly.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]