Компилятор
сlang HEAD 10.0.0 имеет интересный баг при определении дружественной функции в классе.
Если объявить один класс дружественным другому, а затем в этом дружественном классе определить дружественную ему функцию, то эта функция транзитивно будет иметь доступ к членам класса, который предоставил изначально дружбу.
Вот демонстрационная программа, которая успешно компилируется компилятором
clang HEAD 10.0.0
#include <iostream>
class A
{
friend class B;
int m;
};
class B
{
friend void f( A *p ) { p->m = 10; }
};
int main()
{
}
Однако, если определить эту функцию вне класса, как показано ниже
#include <iostream>
class A
{
friend class B;
int m;
};
class B
{
friend void f( A *p );
};
void f( A *p ) { p->m = 10; }
int main()
{
}
то в этом случае компилятор уже сообщит об ошибке, что функция f
не имеет доступа к приватным членам класса
A.
rog.cc:14:21: error: 'm' is a private member of 'A'
void f( A *p ) { p->m = 10; }
^
prog.cc:6:9: note: implicitly declared private here
int m;
^
1 error generated.
Чтобы не было сомнений, что это баг компилятора, приведу цитату из стандарта C++ 17 (14.3 Friends)
цитата: |
10 Friendship is neither inherited nor transitive |
|