Пространства имен и перегрузка операторов в C++

При создании библиотеки в определенном пространстве имен часто бывает удобно предоставить перегруженные операторы для классов в этом пространстве имен. Кажется (по крайней мере, с 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&);

Судя по моему тестированию, они оба работают нормально. Есть ли практическая разница между этими двумя вариантами? Любой из подходов лучше?

Возможный дубликат Пространства имен и разрешение оператора

user9645477 17.04.2018 05:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
38
1
18 847
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы должны определить их в пространстве имен библиотеки. Компилятор все равно найдет их с помощью поиска, зависящего от аргументов.

Не нужно загрязнять глобальное пространство имен.

Другая причина использования пространства имен библиотеки: эта почта содержит пример, в котором использование глобального пространства имен не работает.

Tim 15.06.2015 14:20

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

На самом деле, если вы определяете свои перегрузки в определении своего класса, это становится спорным вопросом:

namespace Lib {

class A {
public:
    A operator+(const A&);
};

} // namespace Lib

Это может быть плохой идеей, поскольку это означает, что если B может быть неявно преобразован в A, но не является подклассом A, тогда A + B работает, а B + A - нет. Конечно, это не обязательно имеет значение, например, если ваш домашний стиль все равно запрещает неявное преобразование между определяемыми пользователем типами.

Steve Jessop 05.10.2008 18:30

Я согласен: есть проблема, что A + B работает, но не B + A (скажем, A - это класс, имитирующий комплексное число, а B - int). Другая проблема заключается в том, что недружественный оператор + функции увеличивают инкапсуляцию класса, тогда как метод класса уменьшает ее.

paercebal 12.10.2008 04:38

Помещение его в пространство имен библиотеки работает из-за Поиск по Кенигу.

Действительно, поиск Koenig был создан именно для того, чтобы вы могли поместить функцию в пространство имен Lib и при этом правильно ее перегружать. См. Исключительные элементы C++ 31-32.

tenpn 17.10.2008 12:20

Другие вопросы по теме