Я считаю, что clang ошибочно разрешает доступ к встроенным функциям дружественных функций к данным в охватывающей области. Оба gcc и vs2013 отклоняют этот код

Функция friend f не имеет доступа к частному члену класса-оболочки A.

#include <iostream>

class A{
    const static int p = 1;
    class B {
        friend void f() {
            std::cout << p << '\n';
            std::cout << q << '\n';
        }
    };
public:
    const static int q = 2;
};
void f();

int main()
{
    f();
}

По крайней мере, я думаю, что [class.nest]/4 в N4140 говорит (см. ниже).

§9.7/4

Как функция-член, функция друга (11.3), определенная внутри вложенный класс находится в лексической области этого класса; он подчиняется тому же правила связывания имен как статическая функция-член этого класса (9.4), но у него нет специальных прав доступа к членам закрытого класс.

живой пример

Ответы

Ответ 1

Я считаю, что вы правы, поскольку и Visual Studio, и GCC правильно отклоняют код на основе указанной вами спецификации. Clang, похоже, ошибочен, разрешив доступ к переменной A private member variable p из функции friend f(), потому что f() является другом B, а не A.

Для хорошего обсуждения возможностей функций друга см. ответ с наивысшим голосом в следующем сообщении SO: Какая область функций встроенного друга