Где следует размещать перегрузки операторов, не являющихся членами? - PullRequest
16 голосов
/ 02 сентября 2010

Я хочу перегрузить operator<< для моего класса. Должен ли я добавить это перегруженное определение в пространство имен std? (поскольку ostream operator<< является частью пространства имен std) Или я должен просто оставить его в глобальном пространстве имен?

Короче говоря:

class MyClass {

};

namespace std {
    ostream& operator<< ( ostream& Ostr, const MyClass& MyType ) {}
}

OR

class MyClass {

};

std::ostream& operator<< ( std::ostream& Ostr, const MyClass& MyType ) {}

Что является более подходящим и почему? Заранее спасибо за ваши ответы.

Ответы [ 3 ]

28 голосов
/ 02 сентября 2010

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

Это позволит оператору быть найденным во время разрешения перегрузки с использованием аргументно-зависимого поиска (ну, фактически, поскольку ostream находится в пространстве имен std, перегрузка перегрузки также будет найдена, если вы поместите его в пространство имен std, но нет причин делать это).

С точки зрения передовых методов проектирования, перегрузка оператора является частью интерфейса вашего класса, а не интерфейса ostream, поэтому он принадлежит к тому же пространству имен, что и ваш класс (см. Также у Херба Саттера). Пространства имен и принцип взаимодействия ).

С точки зрения написания совместимого со стандартами и переносимого кода нельзя перегрузить оператор в пространство имен std. Хотя вы можете добавить специализации шаблонов для пользовательских объектов в пространство имен std, вы не можете добавить дополнительные перегрузки функций.

7 голосов
/ 02 сентября 2010

Не добавляйте его в пространство имен std, поместите его в то же пространство имен, что и ваш класс.Цель пространства имен - предотвратить столкновения.Стандарт гласит:

17.4.3.1 Зарезервированные имена

Для программы на C ++ не определено добавлять объявления или определения в пространство имен std или пространства имен в пространстве имен std, если толькоиначе указано.Программа может добавить специализации шаблона для любого стандартного шаблона библиотеки в пространство имен std.Такая специализация (полная или частичная) стандартного шаблона библиотеки приводит к неопределенному поведению, если только объявление не зависит от определенного пользователем имени внешней ссылки и если специализация не соответствует требованиям стандартной библиотеки для исходного шаблона.

6 голосов
/ 02 сентября 2010

Не добавлять в стандартное пространство имен.Причина: если бы все это делали, стандартное пространство имен имело бы кучу столкновений имен, что отрицательно сказывается на цели пространства имен.

Ваша цель состоит в том, чтобы ваш класс был «ostream-способен».Для этого не обязательно находиться в стандартном пространстве имен.Пока это в любом пространстве имен, в котором объявлен ваш класс, у вас все в порядке.Поместить его в стандартное пространство имен было бы плохой практикой.

...