Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

friend declaration not forward declaring

Tags:

c++

c++11

My understanding was that a friend declaration could also serve as a forward declaration for a class if the class specifier was used, as in this example:

class A
{
    friend class B;
    B* b;
};

class B {};

int main() {}

However, g++ (4.6.3 and 4.7.0) gives me the following error (g++-4.7 should have support for extended friend declarations), which is expected without a forward declaration:

main.cpp:6:2: error: ‘B’ does not name a type

In an attempt to confirm my expectations that the friend class B; should serve as a forward declaration, I found this answer and this answer, but neither was conclusive (or I couldn't conclude much from them at least) so I attempted to consult the c++11 standard and found this example:

class X2 {
    friend Ct; // OK: class C is a friend
    friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-specifier declares new class
}

Based on my reading of the the third declaration, my friend class B should be an elaborated-type-specifier declaring a new class.

I am just starting to understand official standard wording, so I must be missing something. What am I misunderstanding?

like image 922
JaredC Avatar asked Jan 01 '13 22:01

JaredC


1 Answers

Take a look at 11.3 paragraph 11:

For a friend class declaration, if there is no prior declaration, the class that is specified belongs to the innermost enclosing non-class scope, but if it is subsequently referenced, its name is not found by name lookup until a matching declaration is provided in the innermost enclosing nonclass scope.

Example:

class X;
void a();
void f() {
  class Y;
  extern void b();
  class A {
  friend class X;  // OK, but X is a local class, not ::X
  friend class Y;  // OK
  friend class Z;  // OK, introduces local class Z.
  friend void a(); // error, ::a is not considered
  friend void b(); // OK
  friend void c(); // error
  };
  X *px;           // OK, but ::X is found
  Z *pz;           // error, no Z is found
}
like image 108
aschepler Avatar answered Sep 27 '22 20:09

aschepler