При создании библиотеки в определенном пространстве имен часто бывает удобно предоставить перегруженные операторы для классов в этом пространстве имен. Кажется (по крайней мере, с g ++), что перегруженные операторы могут быть реализованы либо в пространстве имен библиотеки:
namespace Lib {
class A {
};
A operator+(const A&, const A&);
} // namespace Lib
или глобальное пространство имен
namespace Lib {
class A {
};
} // namespace Lib
Lib::A operator+(const Lib::A&, const Lib::A&);
Судя по моему тестированию, они оба работают нормально. Есть ли практическая разница между этими двумя вариантами? Любой из подходов лучше?





Вы должны определить их в пространстве имен библиотеки. Компилятор все равно найдет их с помощью поиска, зависящего от аргументов.
Не нужно загрязнять глобальное пространство имен.
Другая причина использования пространства имен библиотеки: эта почта содержит пример, в котором использование глобального пространства имен не работает.
Вы должны определить его в пространстве имен, потому что синтаксис будет менее подробным и не загромождает глобальное пространство имен.
На самом деле, если вы определяете свои перегрузки в определении своего класса, это становится спорным вопросом:
namespace Lib {
class A {
public:
A operator+(const A&);
};
} // namespace Lib
Это может быть плохой идеей, поскольку это означает, что если B может быть неявно преобразован в A, но не является подклассом A, тогда A + B работает, а B + A - нет. Конечно, это не обязательно имеет значение, например, если ваш домашний стиль все равно запрещает неявное преобразование между определяемыми пользователем типами.
Я согласен: есть проблема, что A + B работает, но не B + A (скажем, A - это класс, имитирующий комплексное число, а B - int). Другая проблема заключается в том, что недружественный оператор + функции увеличивают инкапсуляцию класса, тогда как метод класса уменьшает ее.
Помещение его в пространство имен библиотеки работает из-за Поиск по Кенигу.
Действительно, поиск Koenig был создан именно для того, чтобы вы могли поместить функцию в пространство имен Lib и при этом правильно ее перегружать. См. Исключительные элементы C++ 31-32.
Возможный дубликат Пространства имен и разрешение оператора