What is the reason for limiting the declaration of friend functions in local classes?
class A { friend void foo(){}; // OK }; int main() { class B { friend void foo(){}; // ERROR }; } What is the reason for limiting the declaration of friend functions in local classes?
class A { friend void foo(){}; // OK }; int main() { class B { friend void foo(){}; // ERROR }; } Nobody forbids you to declare friendly functions to a local class. In your example, it is not the restriction on the declaration of friend functions as such that is triggered, but the restriction on the definition of friend functions directly inside the definition of a local class.
We can say that the situation stems from the peculiarities of using an unqualified name in friend-declarations in local classes . Qualified names in friend-declarations can be used in the usual way (i.e., as always with qualified names, such friend-announcements should refer to already known functions)
void foo() {} int main() { class A { friend void foo(); // <- Так нельзя }; class B { friend void ::foo(); // <- А так можно }; } The peculiarity of an unqualified name is that, according to the rules of friend-declarations, such an announcement refers to an entity in the nearest non-class encompassing scope . In the above example, the friend declaration in class A refers to the name of the function foo , local to main .
This interpretation of an unqualified name is necessary because it is the only way local classes can refer to each other. For obvious reasons, there are no qualified names for such classes.
What is interesting is that you can still “save” such a friend declaration by forcibly dragging an existing function declaration with the same name into the local scope.
void foo() {} int main() { void foo(); // Объявление ссылается на `::foo` class A { friend void foo(); // <- Так можно // Ссылается на локальное имя `foo` в main, которое ссылается на `::foo` }; } But this loophole does not apply to the definitions of new functions (as in your example) - it would actually try to define a local function in main .
You may notice: why not modify the specification of friend-declarations and say that unqualified names in definitions refer to entities in the nearest scope covering the namespace level?
I see no technical limitations for such an implementation. With only a remark that this will lead to a different interpretation of unqualified names in friend-declarations and in friend-definitions. What is ugly.
The relevance of this topic, by the way, has potentially grown with C ++ 14, in which local classes have become completely not as local as they were before
auto foo() { struct S { void bar() {} }; return S(); } int main() { auto a = foo(); a.bar(); decltype(a) b; b.bar(); } I think the problem is that the friend declaration does not enter the declared function in the declaration area. The function is invisible. Therefore, it does not make sense to define a friend function in the local class declaration area.
When such a definition of a friend function occurs in a non-local class declaration, an argument-dependent search (ADL) can be included, which considers associative namespaces and thus finds the function declared in the class.
Source: https://ru.stackoverflow.com/questions/931605/
All Articles