Reputation: 213
I have created my own floating point types to perform some tests. The goal is that these types can be used out of the box with existing code by just changing a typedef or a template parameter. For example with the Eigen lib I want to be able to do something like Eigen::Matrix<my_type, -1, -1>
and do stuff like inverting the matrix etc. To achieve this, I have overloaded all relevant operators and implemented the functions in the math library.
A problem occurs now when the ternary operator is used in the code that should be executed with my types. For example with the Eigen library I get:
error: operands to ‘?:’ have different types ‘my_type’ and ‘double’
124 | Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h:124:42: note: and each type can be converted to the other
I understand that the left and right side of the ':' are different types and the compiler is not sure which one to use, since it would be possible to convert in both directions. But why is it not simply using the result type (Scalar in this case, which is a template parameter)? Is there a way to solve this without changing the implementation of e.g. the Eigen lib? It is not possible to overload the ternary operator and I need the possibility to convert from double to my_type and vice versa.
Upvotes: 1
Views: 669
Reputation:
Put it this way:
It should be possible to rewrite your code like so:
auto tmp = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
Scalar a = tmp;
Since tmp
needs to have a defined type of its own, the ternary operator needs to return a consistent type.
In your case, you can force both branches to return the same thing by explicitly casting the branch returning the unexpected type:
Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(Scalar(1)/conj(tri(i,i)));
Alternatively, you can use a one-shot lambda as a replacement for the ternary operator.
Scalar a = [&]() -> Scalar {
if (Mode & UnitDiag) {
return Scalar(1);
else {
return Scalar(1)/conj(tri(i,i))
}
}();
Upvotes: 3