When I have a numeric type, which defines operator<
for double, but not for int, comparision with int literals does not work. This is a problem, as parts of the standard library, i.e. std::complex
contain int literals.
Can I make the compiler treat int literals as double when using the type?
Simplified example:
// 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
The failure happens inside the _Div
method of std::complex
at
template<class _Other> inline
void _Div(const complex<_Other>& _Right)
// ...
else if ((_Rightimag < 0 ? -_Rightimag : +_Rightimag)
which causes the error:
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
]
I think probably the code in std::complex
should be _Rightimag < static_cast<_Other>(0)
to work with all numeric types, but I have to work with what the stdlib provides.
As the other type is from a library as well, I am looking for a way to add the implicit conversion to my code.
For the actual code: I am using ceres, which lets you define functors with a templated scalar type for autodifferentiation. The scalar is both evaluated as T
and as Jet<T, N>
.
Ceres defines operator<(const Jet<T, N>&, const T&)
, which allows for jet < 0.0
but not for jet < 0
.
In my code I can work around the problem by using doubles or explicitely casting integers to the template type T
, but when I try to work with complex<T>
I get into trouble for the methods which compare against integer literals, like the _Div
method above.
The std::complex
template is not required to work with general types. The Standard says [complex.numbers]/2:
The effect of instantiating the template
complex
for any type other thanfloat
,double
, orlong double
is unspecified.
If you need to generalize any other numeric-like type to a complex-like type, you should be using some different library or implementing your own.