Я хочу добавить, почему вы не должны добавлять operator+
для std::array
.Или, в более общем смысле, почему вы должны только добавлять операторы (или, скорее, свободные функции) в пространство имен того типа, с которым они работают (что запрещено в случае std
).
Для одного выневозможно поместить оператор в пространство имен A
, а затем правильно использовать его в пространстве имен B
(без using namespace A;
):
namespace A
{
using coord = std::array<double, 3>; // Putting this in the global namespace doesn't help.
coord operator+(const coord& right, const coord& left)
{
return coord { right[0] + left[0], right[1] + left[1], right[2] + left[2] };
}
}
auto foo()
{
A::coord x, y;
return x + y; // doesn't see the operator
}
https://godbolt.org/z/XUR_NX
Осталось только одно местопоставить оператор это глобальное пространство имен.Если это не доставляет вам неудобств, вот причина, по которой это должно произойти: правила поиска имен довольно скоро сломают вам шею.
Что если мы захотим написать шаблон, который использует ваш operator+
?Должно работать нормально, верно?
template<class ... T>
auto add(T ... t)
{
return (t + ...);
}
https://godbolt.org/z/Ox8_r5
Да, это работает!Ну, , пока кто-то не добавит любой operator+
ближе к шаблону :
namespace A
{
struct X{};
void operator+(X, X);
template<class ... T>
auto add(T ... t)
{
return (t + ...); // won't find the correct operator+ for T=coord
}
}
https://godbolt.org/z/ctcfxr
На этом поиск имени останавливается operator+
.Поскольку ваш правильный (для std::array
) отсутствует в namespace std
(где std::array
), он не может быть найден с помощью ADL (поиск, зависящий от аргумента).В этот момент у вас нет выбора.