Где должны быть размещены перегрузки операторов, не являющихся членами?
Я хочу перегрузить operator<<
для моего класса. Должен ли я добавить это перегруженное определение в пространство имен std
? (так как ostream operator<<
является частью пространства имен std
). Или я должен просто оставить его в глобальном пространстве имен?
Короче:
class MyClass {
};
namespace std {
ostream& operator<< ( ostream& Ostr, const MyClass& MyType ) {}
}
ИЛИ
class MyClass {
};
std::ostream& operator<< ( std::ostream& Ostr, const MyClass& MyType ) {}
Что более подходит и почему? Заранее благодарим за ваши ответы.
Ответы
Ответ 1
Вы должны перегрузить оператор в том же пространстве имен, что и ваш класс.
Это позволит оператору найти во время разрешения перегрузки, используя зависящий от аргумента поиск (ну, фактически, поскольку ostream
находится в пространстве имен std
, перегрузка перегрузки также будет найдена, если вы поместите ее в пространство имен std
, но для этого нет оснований).
С точки зрения хорошей практики проектирования перегрузка оператора является скорее частью интерфейса вашего класса, чем интерфейсом ostream
, поэтому она принадлежит к тому же пространству имен, что и ваш класс (см. также Herb Sutter Пространства имен и принцип интерфейса).
С точки зрения написания стандартно-совместимого и переносимого кода вы не можете перегрузить оператор в пространство имен std
. Хотя вы можете добавлять специализированные шаблоны для определяемых пользователем объектов в пространство имен std
, вы не можете добавлять дополнительные перегрузки функций.
Ответ 2
Не добавляйте к стандартному пространству имен.
Причина. Если бы все это сделали, стандартное пространство имен имело бы кучи конфликтов имен, которые побеждают цель пространства имен.
Ваша цель состоит в том, чтобы ваш класс был "активным". Для этого не нужно находиться в стандартном пространстве имен. До тех пор, пока это объявлено в каком-либо объявлении вашего класса, вы в порядке. Включение его в стандартное пространство имен было бы плохой практикой.
Ответ 3
Не добавляйте его в пространство имен std
, поместите его в том же пространстве имен, что и ваш класс. Цель пространства имен - предотвращать конфликты. В стандарте говорится
17.4.3.1 Зарезервированные имена
Это undefined для программы на С++. добавлять декларации или определения к пространства имен или пространства имен внутри пространство имен std, если иное указано. Программа может добавить шаблон специализации для любого стандарта шаблон библиотеки в пространство имен std. Такая специализация (полная или частичная) стандартной библиотеки результат шаблона в undefinedесли декларация не зависит от определяемое пользователем имя внешней связи и если специализация не встречается требования к стандартной библиотеке для исходный шаблон.