LINUX.ORG.RU

C++ классы, friend функции, подскажите место в стандарте

 , friend, standart,


1

1

Добрый день.
Подскажите место в стандарте, где разъясняется следующее поведение:

#include <iostream>

using namespace std;

class A {
    int i_ = 555;

    friend void f0(A& a) { 
        cout << a.i_ << endl; 
    }

    friend void f1() {
        A a;
        cout << a.i_ << endl;
    }
};

// Если не указать эту строку, 
// то дальнейший вызов f1() не удастся
void f1();

int main() {
    A a;

    f0(a);

    // Здесь будет ошибка, если выше
    // нет объявления f1() вне класса
    f1();  

    return 0;
}
Где в стандарте написано, что в данном случае для f0 достаточно объявления в классе, а для f1 нет? Заранее спасибо.

UPD0
Нашел ответ.
В книге Язык программирования C++ Специальное издание (Бьерн Страуструп)
11.5.1. Поиск друзей
...

Дружественная функция может явно объявляться таким же образом, что и дружественный класс; или же ее можно искать по типу аргументов (§8.2.6) даже в случае, когда она объявлена вовсе не в самой близкой из охватывающих областей видимости.
Например:

void f(Matrix& m) {
    invert(m); // invert() - друг класса Matrix
}
Итак, дружественная классу функция или объявляется в непосредственно охватывающей области видимости, или имеет аргумент типа класса (или производного от него класса) (§13.6), или вообще не может быть найдена.
...

8.2.6. Поиск имен
Чаще всего функция с аргументом типа Т определяется в том же пространстве имен, что и тип Т. Поэтому, если функцию не удается найти в контексте, где она используется, поиск продолжается в пространстве имен ее аргументов.
Например:
namespace Chrono {
    class Date{ /*...*/};
    boot operator==(const Date&, const std::string&);
    std::string format(const Date&); // выдать строковое представление
    // ...
}

void f(Chrono::Date d, int i) {
    std::string s = format(d); // Chrono::format()
    std::string t = format(i); // error: нет format() в области видимости
}

★★★★★

Последнее исправление: rumgot (всего исправлений: 5)

Это же просто argument dependent lookup, нет ?

anonymous
()

С виду ADL

anonymous
()
Ответ на: комментарий от fluorite

А чего тогда квалифицированный вызов не работает? A::f1();

anonymous
()

Возможно, эти параграфы определяют эти функции как доступные только по ADL. Лучше не нашёл, но кажется, что должны быть.

class.friend-6-7:

A function can be defined in a friend declaration of a class if and only if the class
is a non-local class ([class.local]), the function name is unqualified, and the function has namespace scope.

Such a function is implicitly an inline function ([dcl.inline]).
A friend function defined in a class is in the (lexical) scope of the class in which it is defined.
A friend function defined outside the class is not ([basic.lookup.unqual]).

basic.lookup.unqual-9:

Name lookup for a name used in the definition of a friend function defined inline in the class
granting friendship shall proceed as described for lookup in member function definitions.
If the friend function is not defined in the class granting friendship, name lookup in the friend
function definition shall proceed as described for lookup in namespace member function definitions.
xaizek ★★★★★
()
3 мая 2020 г.
Ответ на: комментарий от xaizek

Возможно, эти параграфы определяют эти функции как доступные только по ADL. Лучше не нашёл, но кажется, что должны быть.

Ты вообще нерелевантную фигню запостил. Релевантная — в https://timsong-cpp.github.io/cppwp/n4659/namespace.memdef#3

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.