Стандарты программирования на С++. 101 правило и рекомендация | страница 100
>x3 = N::operator+(x1, x2);
Грустная картина — невозможность использовать естественный синтаксис оператора, который, собственно, и был главной целью введения перегрузки операторов в язык программирования. Другой способ заставить работать приведенный ранее код — использовать инструкцию >using
:
>using N::operator+;
>// или: using namespace N;
>x3 = x1 + x2;
Применение >using
— совершенно нормальная и приемлемая вещь (см. рекомендацию 59), но все проблемы решаются гораздо проще, если автор >X
изначально поступает корректно и помещает оператор >operator+
, работающий с объектами >X
, в то же пространство имен, где находится >X
.
"Оборотная сторона" этого вопроса рассматривается в рекомендации 58.
Пример 1. Операторы. Операторы работы с потоками >operator<<
и >operator>>
для объектов некоторого класса >X
, вероятно, относятся к наиболее ярким примерам функций, которые вполне очевидно являются частью интерфейса класса >X
, но при этом всегда представляют собой свободные функции (это обязательное условие, поскольку левый аргумент этих операторов — поток, а не объект >X
). Та же аргументация применима и к другим операторам, не являющимся членами >X
. Убедитесь, что ваши операторы находятся в том же пространстве имен, что и класс, с которым они работают. Если у вас есть возможность выбора, лучше делать операторы и все прочие функции не членами и не друзьями класса (см. рекомендацию 44).
Пример 2. Прочие функции. Если автор >X
предоставляет именованные вспомогательные функции, которые получают в качестве аргументов объекты >X
, они должны находиться в том же пространстве имен, что и >X
. В противном случае вызывающий код, использующий объекты >X
, будет не в состоянии работать с этими именованными функциями без явной квалификации их имен или применения инструкции >using
.
[Stroustrup00] §8.2, §10.3.2, §11.2.4 • [Sutter00] §31-34
58. Храните типы и функции в разных пространствах имен, если только они не предназначены для совместной работы
Оберегайте ваши типы от непреднамеренного поиска, зависящего от аргументов (argument-dependent lookup — ADL, известный также как поиск Кёнига); однако преднамеренный поиск должен завершаться успешно. Этого можно добиться путем размещения типов в своих собственных пространствах имен (вместе с непосредственно связанными с ними свободными функциями; см. рекомендацию 57). Избегайте помещения типов в те же пространства имен, что и шаблоны функций или операторов).