Это неоднозначно, потому что компилятор просматривает сигнатуру функции только для проверки на неоднозначность, а не тело функции. В вашем примере это сигнатура функции:
template<typename pointType>
pointType operator-(pointType a, const pointType & b)
Здесь параметр шаблона pointType
может быть выведен как std::chrono::time_point
. Однако в заголовке chrono
для std::chrono::time_point
(https://en.cppreference.com/w/cpp/chrono/time_point/operator_arith2) уже объявлен двоичный оператор минус. Именно это и вызывает ошибку неоднозначности.
Чтобы решить эту проблему, вы должны сначала подумать, нужен ли вам такой обобщенный c двоичный оператор минус. Проблема, с которой вы сталкиваетесь в настоящее время, не будет уникальной для std::chrono::time_point
, но также будет возникать с любым другим заголовком, который содержит класс с двоичным оператором минус-члена или не являющимся членом, где оба аргумента имеют один и тот же тип (или могут быть неявно). преобразовать в тот же тип). Возможно простой набор перегрузок функций для рассматриваемых типов:
template<typename T>
std::vector<T> operator-(const std::vector<T>& a, const std::vector<T>& b);
template<typename T, size_t N>
std::array<T,N> operator-(const std::array<T,N>& a, const std::array<T,N>& b);
Это был бы самый безопасный вариант. Вы также не можете использовать перегрузку операторов вообще и придерживаться обычной функции:
template<typename T>
T pointwise_subtract(const T& a, const T& b);
Если у вас есть компилятор c ++ 20, вы можете использовать понятия. Если вы настаиваете на использовании шаблонов операторов, не являющихся членами, вам, возможно, придется использовать метапрограммирование шаблонов на основе SFINAE, более продвинутый и менее читабельный метод:
//enable this template if the type T has a member method "size" and
// subscript operator accepting variables of type "size_t"
template<typename T, typename=std::void_t<
decltype(std::declval<T>().size()),
decltype(std::declval<T>()[std::declval<size_t>()])
>
T operator-(const T& a, const T& b);
Это устранит вашу ошибку неоднозначности.