libigl-python-bindings
libigl-python-bindings copied to clipboard
Why does return require cast to double?
I'm trying to understand a compiler error and I think it's related to this choice:
https://github.com/libigl/libigl-python-bindings/blob/6bf30bcc3fc34c148da0bb9f029e181bf10f4d82/src/unproject_on_line.cpp#L72
How come double(t)
is needed here rather than just t
?
changing to t
gives this error
...unproject_on_line.out.cpp:350:1: error: return type 'tuple<double, [...]>'
must match previous return type 'tuple<float, [...]>' when lambda expression has unspecified explicit return type
return callit_unproject_on_line<Map_uv, Matrix_uv, Scalar_uv,Map_m, Matrix_m, Scalar_m,Map_vp, Matrix_vp, Scalar_vp,Map_origin, Matrix_origin, ...
^
Not sure how to parse that.
Ah this is a gotcha in NPE:
Under the hood, NPE generates a templated function (in this case callit_unproject_on_line
) with your code. It then generates a switch statement which calls this function with the appropriate types depending on what gets passed in to the python binding.
In the posted code, t
has type npe_Scalar_uv
which can be different depending on the type of uv
. Thus, you end up with different return types for different template instantiations of callit_unproject_on_line
which is not valid C++.
Note that npe::move
handles this by casting your Eigen::Matrix
types to PyObject*
(or whatever pybind11's wrapper for this is) smartly (handing memory ownership and avoiding copies), so your return types always match with npe::move
.
To return a single scalar, casting to the highest precision type seems like the reasonable thing to do here.
Makes sense. Maybe to generate fewer templates t should just be defined to be double in the first place.
On Wed, Apr 20, 2022, 1:05 PM Francis Williams @.***> wrote:
Ah this is a gotcha in NPE:
Under the hood, NPE generates a templated function (in this case callit_unproject_on_line) with your code. It then generates a switch statement which calls this function with the appropriate types depending on what gets passed in to the python binding.
In the posted code, t has type npe_Scalar_uv which can be different depending on the type of uv. Thus, you end up with different return types for different template instantiations of callit_unproject_on_line which is not valid C++.
Note that npe::move handles this by casting your Eigen::Matrix types to PyObject* (or whatever pybind11's wrapper for this is) smartly (handing memory ownership and avoiding copies), so your return types always match with npe::move.
To return a single scalar, casting to the highest precision type seems like the reasonable thing to do here.
— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-python-bindings/issues/138#issuecomment-1104191270, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGMSOLHD4FPXXBJ6ZS3VGA2OJANCNFSM5T2ICD7A . You are receiving this because you authored the thread.Message ID: @.***>