Created on1999-09-08.00:00:00 last changed277 months ago
Proposed resolution (10/00):
In_N4868_.9.8.2.3 [namespace.memdef] paragraph 3, change
When looking for a prior declaration of a class or a function declaredas a friend, scopes outside the innermost enclosing namespace scope arenot considered.to
When looking for a prior declaration of a class or a function declaredas a friend, and when the name of the friend class or function isneither a qualified name nor atemplate-id, scopes outside theinnermost enclosing namespace scope are not considered.Also, change the example in that paragraph as follows:
void h(int); template <class T> void f2(T); namespace A { class X { friend void f(X); // A::f(X) is a friend friend void f2<>(int); // ::f2<>(int) is a friend ...John Spicer:I believe the standard is not clear with respect to this example:
namespace N { template <class T> void f(T); namespace M { struct A { friend void f<int>(int); // okay - refers to N::f }; } }At issue is whether the friend declaration refers toN::f, orwhether it is invalid.A note in6.4.2 [basic.scope.pdecl] paragraph 6says
friend declarations refer to functions or classesthat are members of the nearest enclosing namespace ...I believe itis intended to meanunqualified friend declarations. Certainlyfriend void A::B() need not referto a member of the nearest enclosingnamespace. Only when the declarator is unqualified (i.e., it is a declarationand not a reference) does this rule need to apply. The presence of anexplicit template argument list requiresthat a previous declaration be visible and renders this a reference and nota declaration that is subject to this rule.
Mike Miller:_N4868_.9.8.2.3 [namespace.memdef] paragraph 3says,
When looking for a prior declaration of aclass or a function declared as a friend, scopes outside theinnermost enclosing namespace scope are not considered.On the other hand, the friend declaration would be a syntaxerror iff weren't declared as a template name; it wouldseem very strange not to find the declaration that made thefriend declaration syntactically correct.However, it also seems strange to treat this case differentlyfrom ordinary functions and from templates:
namespace N { template <class T> void f(T); void g(); namespace M { struct A { friend void f<int>(int); // N::f template <class T> friend void f(T); // M::f friend void g(); // M::g }; } }John Spicer:This section refers to "looking for a prior declaration". Thisgets back to an earlier discussion we've had about the difference betweenmatching two declarations of the same name and doing name lookup. I wouldmaintain that inf<int>thef is looked up using a normal lookup. Inpractice, this is really how it has to be done because the declarationcould actually bef<int>::x.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2003-04-25 00:00:00 | admin | set | status: dr -> tc1 |
| 2000-11-18 00:00:00 | admin | set | status: ready -> dr |
| 2000-05-21 00:00:00 | admin | set | status: review -> ready |
| 2000-02-23 00:00:00 | admin | set | messages: +msg222 |
| 2000-02-23 00:00:00 | admin | set | status: open -> review |
| 1999-09-08 00:00:00 | admin | create | |