TGViewer
C++: Хроники Дурки🚑 C++: Хроники Дурки🚑 @cpp_durka · 916 subscribers
Post #77 1.15K
Всяко разное болезненное есть в С++, из всего болезненного одно из самых болезненных - это friend функции. Если жизнь и рассудок дороги вам - не объявляйте такие функции вообще никогда.

С ними связаны много разных интересных, скажем так особенностей, про которые эксперты из комментариев скажут, что все логично, так и надо, и вообще, а как вы хотели иначе?

Никогда такого не было и вот опять - нашел следующую веселую приколюху.

Пусть у нас есть вот такой класс:



class A {
int x;
public:
A(int a) : x(a) {}
class B {
int y;
public:
B(int b) : y(b) {}
void f(A& a, B& b){
b.y = 1;
a.x = 1;
}
};
};


Да, странненький и убогенький, но вообще весь мой код примерно такой.

Так вот в нем есть класс, у него есть вложенный класс, и в нем есть функция, которая модифицирует объекты и своего класса, и того, в который он вложен.


void f(A& a, B& b){
b.y = 1;
a.x = 1;
}


И как мы можем видеть из ссылки выше - все прекрасно работает, и проблем ни у кого не вызывает.


int main() {
auto a = A(1);
auto b = A::B(2);

b.f(a, b);

return 0;
}


Но давайте теперь сделаем эту функцию friend и вынесем за пределы класса.


class A {
int x;
public:
A(int a) : x(a) {}
class B {
int y;
public:
B(int b) : y(b) {}
friend void f(A& a, B& b);
};
};

void f(A& a, A::B& b){
b.y = 1;
a.x = 1;
}


Милорд, у вас родился кудяблик, и эта штука перестала компилироваться:


int main() {

auto a = A(1);
auto b = A::B(2);

f(a, b);

return 0;
}


Потому что что? Потому что правильно, мы дружим только с B, а вот с A не дружим.


<source>:15:7: error: 'x' is a private member of 'A'
15 | a.x = 1;
| ^
<source>:2:9: note: implicitly declared private here
2 | int x;
|


Мне тут поступал запрос на глубину моих постов, поэтому я потратил целых 10 минут на изучение вопроса прежде чем пошел строчить гневный пост в интернеты, и нашел вот такое:


https://cplusplus.github.io/CWG/issues/3193.html

тут что-то про inhabiting the class scope, и насколько я понял, вот такая ошибка компиляции - это самовольство компиляторов, а в стандарте про это вроде как ничего внятного сказано не было... Или было, но я, в скудоумии своем, не разобрался...

Кароче, friend - это одна их тех вещей, которых я стараюсь избегать в своем коде... Рано или поздно я начну избегать всего С++
godbolt.org Compiler Explorer - C++ class A { int x; public: A(int a) : x(a) {} class B { int y; public: B(int b) : y(b) {} void f(A& a, B& b){ b.y = 1; a.x = 1; } }; }; int main() { auto a = A(1); …
  • ❤ 17
  • 😁 10
  • 👍 2
More from @cpp_durka
  1. Sep 8, 2026Мошенники заставили пенсионерку из Москвы переписать квартиру на Rust
  2. Aug 24, 2026Если кто не знаком с библиотекой nlohmann/json - она прекрасна. Мои мысли о том, как должн…
  3. Aug 21, 2026#толькосвоимемы Код взят тут. if (dim == 0) idx_dim = i0; else if (dim == 1) idx_dim = i1;…
  4. Aug 17, 2026Ладно, искать баги в компиляторах весело, но недостаточно. Давайте поиграемся в чуть более…
  5. Aug 10, 2026Ладно, разумеется прошлый пост был набросом. Никогда не обновляйте компиляторы без очень с…
  6. Aug 3, 2026Убедительная просьба - обновляйте компиляторы. Помимо внедрения множества способов выстрел…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →