Существуют ли другие правила относительно ADL или конфликты имен в отношении перегруженных операторов?

Я думаю, что этот пример лучше всего иллюстрирует мой вопрос:

namespace N {

class C {
public:
friend bool operator==(const C& c, const C& x) {
return true;
}
friend bool f(const C& c, const C& x) {
return true;
}
};

class D {
public:
bool operator==(const D& x) {
bool a = C{} == C{};      // this works
return true;
}
bool f(const D& x) {
bool a = f(C{}, C{});     // this does not work
return true;
}
};
}

Я всегда рассматривал перегруженные операторы как функции, за исключением «вызывающего синтаксиса», если хотите. Я только заметил вышеупомянутое различие однако в ADL или правилах поиска имени (я не знаю, какое).

Может кто-нибудь объяснить, почему bool operator==(const C& c, const C& x) найден но bool f(const C& c, const C& x) не является?

2

Решение

Ваш D::f является прячется C::f; если переименовать последнее в C::g и настроить вызов, то он работает нормально (показывая, что функция может быть найденный а также доступ к просто хорошо).

Ваш код на самом деле не вызывает функции оператора напрямую, но это делается для вас языком. Следовательно, вы не используете название функции оператора, поэтому скрытие имени не применяется.

Если ты пишешь operator==(C{}, C{}) (вместо C{} == C{}), тогда вы увидите то же поведение, что и f(C{}, C{}) (демонстрация).

Итак, когда вы говорите: «Я всегда рассматривал перегруженные операторы как функции, за исключением« вызывающего синтаксиса », если хотите», вы уже достигли цели.


Вот несколько стандартов для вас:

[C++11: 13.5/4]: Операторские функции обычно не вызываются напрямую; вместо этого они вызываются для оценки операторов, которые они реализуют (13.5.1 — 13.5.7). Они могут быть явно вызваны, однако, используя оператор-функция-идентификатор как имя функции в синтаксисе вызова функции (5.2.2). [ Пример:

complex z = a.operator+(b); // complex z = a+b;
void* p = operator new(sizeof(int)*n);

— конец примера]

[C++11: 3.3.7/4]: [..] 4) Имя, объявленное в функции-члене, скрывает объявление с тем же именем, область которого распространяется до или после конца класса функции-члена. [..]

[C++11: 3/4]: Имя — это использование идентификатор (2,11), оператор-функция-идентификатор (13.5), буквальный-оператор-идентификатор (13.5.8), преобразование-функция-идентификатор (12.3.2) или Шаблон-идентификатор (14.2), который обозначает сущность или этикетка (6.6.4, 6.1).

([Квалифицированный] оператор-функция-идентификатор здесь ::N::C::operator==.)

2

Другие решения


По вопросам рекламы [email protected]