Why can't forward declared friend class be ref

2020-05-29 22:31发布

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?

标签: c++ friend
3条回答
再贱就再见
2楼-- · 2020-05-29 22:45

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.

查看更多
霸刀☆藐视天下
3楼-- · 2020-05-29 22:48

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]).

查看更多
我欲成王,谁敢阻挡
4楼-- · 2020-05-29 22:57

One way to fix this code is to simply add class keyword:

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

This will forward declare class Y at the global scope, if X is in the global scope.

查看更多
登录 后发表回答