Reputation: 622
I'm using pybind11 and I would like to pass a list of tuples (coordinates) from Python to C++. Here is the example C++ code:
parse_coords(py::list coords) {
std::vector<PointI> coordinates(py::len(coords));
for (size_t i = 1; i < py::len(coords); i++) {
coordinates[i].x = coords[i][0];
coordinates[i].z = coords[i][1];
}
}
Obviously, this does not work. The error I get is cannot convert ‘pybind11::detail::item_accessor’ {aka ‘pybind11::detail::accessor<pybind11::detail::accessor_policies::generic_item>’} to ‘int’ in assignment
How can I pass a list of anything more complicated than an int, which is all the examples I've been able to find?
Upvotes: 1
Views: 4489
Reputation: 648
You have to use py::cast
. If there is no casting function registered for your custom type, or there is a type mismatch, then you are going to get an exception:
Example:
void cast_test(const py::list& l)
{
for(auto it = l.begin(); it != l.end(); ++it)
{
std::cout << it->cast<int>() << std::endl;
}
}
>>> example.cast_test([1,2,3])
1
2
3
>>> example.cast_test([1,2,"a"])
1
2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Unable to cast Python instance to C++ type (compile in debug mode for details)
>>>
Here you can find more details about built in casts: https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html
And here how to add custom type casters: https://pybind11.readthedocs.io/en/stable/advanced/cast/custom.html
Upvotes: 3