Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't forward declared friend class be referred in the class?

Tags:

c++

friend

The following code doesn't compile:

struct X {   friend class Y;   Y* ptr; }; 

The cppreference describes the situation as

... If the name of the class that is used in the friend declaration is not yet declared, it is forward declared on the spot.

If the "spot" means where the friend relationship is declared, then it should be fine to declare the member Y* ptr. Why doesn't it compile? Where in the standard prohibits this?

like image 968
Kan Li Avatar asked Aug 27 '18 18:08

Kan Li


People also ask

What is forward declaration of a class and why is it often essential when using friend functions?

Forward Declaration refers to the beforehand declaration of the syntax or signature of an identifier, variable, function, class, etc. prior to its usage (done later in the program). In C++, Forward declarations are usually used for Classes.

Is it possible to declare friendship with the class template?

Both function template and class template declarations may appear with the friend specifier in any non-local class or class template (although only function templates may be defined within the class or class template that is granting friendship).

Where to put friend class declaration?

By declaring a function as a friend, all the access permissions are given to the function. The keyword “friend” is placed only in the function declaration of the friend function and not in the function definition.

Can you forward declare base class?

A base class MUST be declared (not forward declared) when being declared as a based class of another class. An object member MUST be declared (not forward declared) when being declared by another class, or as parameter, or as a return value.


2 Answers

This is a mistake on the site. It contradicts the standard, which says that friendship declaration is not a substitute for a forward declaration:

7.3.1.2.3 Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup or qualified lookup.

The part about the name not being visible to unqualified or qualified lookup essentially means that the name does not behave like a forward declaration.

like image 131
Sergey Kalinichenko Avatar answered Sep 20 '22 13:09

Sergey Kalinichenko


In addition to the answer of @dasblinkenlight, a note in 3.3.2 Point of declaration lit. 10 explicitly says that a friend declaration does not introduce (and therefore not "forward declare") a class name:

10 [ Note: Friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace ([namespace.memdef]).

like image 29
Stephan Lechner Avatar answered Sep 18 '22 13:09

Stephan Lechner