Давайте учтем эти 3 строки кода из вашего примера:
1. friend class F; // it creates "friend declaration", (that's not the same as ordinary forward declaration
2. class F; // without this forward declaration, F can't be friend to A::C <-- this is ordinary forward declaration
3. friend class ::F; // this is qualified lookup (because of ::), so it needs previous declaration, which you provide in line 2.
Стандарт C ++ в пункте 7.3.1.2, пункт 3 (определения членов пространства имен) говорит:
Объявление друга само по себе не делает имя видимым для
неквалифицированный поиск (3.4.1) или квалифицированный поиск (3.4.3). [ Обратите внимание
имя друга будет видно в его пространстве имен, если совпадающее
объявление предоставляется в области имен (до или после
определение класса предоставления дружбы). —Конечная записка]
И строка 2 точно соответствует требованиям стандарта.
Вся путаница заключается в том, что «объявление друга» является слабым , вам необходимо предоставить твердое предварительное объявление для дальнейшего использования.