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

Функция друга 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), но не имеет специальных прав доступа к членам окружающего класса.

живой пример


person Belloc    schedule 19.07.2015    source источник
comment
Не могли бы вы уточнить, разрешает ли Clang это, но другой выдает вам ошибки? Какой у Вас вопрос?   -  person Some programmer dude    schedule 19.07.2015
comment
Да, это правильно. Я просто хотел бы получить какое-то подтверждение по этому поводу.   -  person Belloc    schedule 19.07.2015
comment
Ты прав. Это должно быть ошибка того, как clang реализовал друзей   -  person Jens Munk    schedule 19.07.2015
comment
clang по-прежнему позволяет это в своей версии 9.0 (C++20)   -  person WaldB    schedule 15.02.2019


Ответы (1)


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

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

person rholmes    schedule 19.07.2015