I attempted to get friend name injection to work with the following snippet:
struct foo
{
friend foo f() { return {}; }
};
int main()
{
auto x = f();
return 0;
}
This fails to compile:
test.cc:8:10: error: use of undeclared identifier 'f'
auto x = f();
^
1 error generated.
I have to declare f
in the outer namespace for the error to vanish.
The standard has an explanation in paragraph 3 of §7.3.1.2:
If a friend declaration in a non-local class first declares a class, function, class template or function template97 the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup (3.4.1) or qualified lookup (3.4.3). [Note: The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship). — end note ]
My question: why do we need an extra declaration of f
at namespace scope for this to compile? Does it have to do with ADL? Is there a (hacky) way around this requirement?