У меня возникли некоторые проблемы с перегрузками операторов шаблонов при входе в пространства имен. Рассмотрим добавление массивов:
// overloads.hpp
#include <array>
namespace mylib {
template <size_t N>
using DoubleArray = std::array<double,N>;
template <size_t N>
DoubleArray<N> operator+( const DoubleArray<N>& lhs, const DoubleArray<N>& rhs ) {return DoubleArray<N>();}
}
Проверка этого в namespace mylib
работает как задумано.
// test.cpp
#include "overloads.hpp"
namespace mylib {
void test()
{
DoubleArray<3> a({1.0,0.0,0.0});
DoubleArray<3> b({0.0,1.0,0.0});
DoubleArray<3> c(a+b); // <-- ok
}
}
Теперь предположим, что у меня есть класс Complex
в пространстве имен mylib::mysublib
, который имеет его собственный operator+
и конструктор из DoubleArray
(этот конструктор должен быть явным, чтобы предотвратить неявное преобразование):
// nested.cpp
#include "overloads.hpp"
namespace mylib {
namespace mysublib {
struct Complex
{
Complex() {};
explicit Complex( const DoubleArray<2>& components );
DoubleArray<2> _components;
};
Complex operator+(const Complex& rhs, const Complex& lhs) {return Complex();}
void testNested()
{
DoubleArray<2> a({1.0,0.0});
DoubleArray<2> b({0.0,1.0});
DoubleArray<2> c(a+b); // <-- no match for ‘operator+’
DoubleArray<2> d( mylib::operator+(a,b) ); // <-- ok
}
}
}
Сообщение об ошибке:
error: no match for ‘operator+’ (operand types are ‘mylib::DoubleArray<2> {aka std::array<double, 2>}’ and ‘mylib::DoubleArray<2> {aka std::array<double, 2>}’)
DoubleArray<2> c(a+b); // <-- no match for ‘operator+’
Почему нельзя перегруженный оператор будет найден при вызове из вложенного пространства имен? Весь смысл перегрузки (в этом примере) будет в чистом синтаксисе. Любые идеи о том, как заставить это работать, или если это вообще возможно?