October 03, 2006
In the following code the declaration of bar *x is fine in
x() because its a member of class foo but its not OK in y()
because its a friend function:

class foo {

    public:

    void x() {
        bar *x;  // This declaration is OK.
    }

    friend void y() {
        bar *x;   // Type bar is unavailable here.
    }

    private:

    struct bar {
	int value;
        bar *next;
    };

};

I don't understand this because I thought that the declaration of a function to be a friend of the class was to allow it to have access to all the private values and types in the class.  That is to say treat the function as if it was a member of the class.

But this is not happening and I am getting frustrated with C++ being so fussy.  It seems to me perfectly reasonable that y() should be able to declare pointers of type bar. The only I can get this to work is to take the declaration of bar outside of the declaration of foo i.e. both are first level declarations.  I don't want that because bar is only supposed to be used by foo.

Thanks,
Edward
October 05, 2006
Hi,

Edward A. Waugh wrote ...
> In the following code the declaration of bar *x is fine in
> x() because its a member of class foo but its not OK in y()
> because its a friend function:
> 
> class foo {
> 
>     public:
> 
>     void x() {
>         bar *x;  // This declaration is OK.
>     }
> 
>     friend void y() {
>         bar *x;   // Type bar is unavailable here.
>     }
> 
>     private:
> 
>     struct bar {
> 	int value;
>         bar *next;
>     };
> 
> };
> 
> I don't understand this because I thought that the declaration of a function to be a friend of the class was to allow it to have access to all the private values and types in the class.  That is to say treat the function as if it was a member of the class.

Friends are NOT members! Therefore y() has no this-pointer and the scope to search for variables is outside the class scope. It might be clearer if you don't define the functions inline:

  class foo {
  public:
      void x();
      friend void y();
  private:
     struct bar {
         int value;
         bar *next;
      };
  };

  // Definition outside

  void foo::x() {
  //   ^^^^^
  // foo:: tells the compiler that x is a class member
     bar *x;  // This declaration is OK.
  }

  void y() {
  //  ^^^^
  // ordinary global function!
     bar *x;      // Type bar is unavailable here.
     foo::bar *z; // this is ok because y() as a friend
                  // is allowed to use foo::bar
  }



- Heinz