Когда у меня есть числовой тип, который определяет operator<
для double, но не для int, сравнение с литералами int не работает. Это проблема, так как части стандартной библиотеки, т. е. std::complex
, содержат литералы int.
Могу ли я заставить компилятор обрабатывать литералы int как двойные при использовании типа?
Упрощенный пример:
// the defined operator
template<typename T>
bool operator<(const Type<T> &lhs, const T &rhs);
complex<Type<T>> complex_number;
1.0 / complex_number; // this fails
Сбой происходит внутри метода _Div
std::complex
в
template<class _Other> inline
void _Div(const complex<_Other>& _Right)
// ...
else if ((_Rightimag < 0 ? -_Rightimag : +_Rightimag)
что вызывает ошибку:
error C2678: binary '<': no operator found which takes a left-hand operand of type 'Type<T>' (or there is no acceptable conversion)
(...)
complex(665): note: while trying to match the argument list '(Type<T>, int)'
[
T=double
]
Я думаю, что код в std::complex
должен быть _Rightimag < static_cast<_Other>(0)
для работы со всеми числовыми типами, но мне приходится работать с тем, что предоставляет stdlib.
Поскольку другой тип также из библиотеки, я ищу способ добавить неявное преобразование в свой код.
Для фактического кода: я использую ceres, который позволяет вам определять функторы с шаблонным скалярным типом для автодифференциации. Скаляр оценивается и как T
, и как Jet<T, N>
.
Ceres определяет operator<(const Jet<T, N>&, const T&)
, что позволяет для jet < 0.0
, но не для jet < 0
.
В моем коде я могу обойти проблему, используя удвоения или явно приводя целые числа к типу шаблона T
, но когда я пытаюсь работать с complex<T>
, у меня возникают проблемы с методами, которые сравниваются с целочисленными литералами, такими как метод _Div
выше.
operator<
дляdouble
, но на самом деле вы определили тот, который принимает произвольный типT
. Корень проблемы в том, что есть два параметра, которые позволяют компилятору вывестиT
, и когда они расходятся во мнениях относительно того, каким должен бытьT
, возникает неоднозначность. Есть способы обойти это (вы помещаете один изT
в невыведенный контекст), но не похоже, что у вас есть контроль над объявлениемoperator<
. Так что в основном это плохой дизайн со стороны авторов той библиотеки, которую вы используете. - person Igor Tandetnik   schedule 10.09.2018std::complex
. - person allo   schedule 10.09.2018<
как дружественного оператора ADL, а не как оператора свободного шаблона. Это решило бы вашу проблему.friend bool operator op(const Jet& f, const T& s) { return f.a op s; }
и т. д. - person Yakk - Adam Nevraumont   schedule 10.09.2018