11

According to the pybind11 documentation https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html:

When including the additional header file pybind11/stl.h, conversions between std::vector<>/std::list<>/std::array<>, std::set<>/std::unordered_set<>, and std::map<>/std::unordered_map<> and the Python list, set and dict data structures are automatically enabled.

However, I cannot for the life of me get this to work. I suppose I am misunderstanding something, so I hope someone can clear it up for me.

Here is what I expected to work:

// Test
std::vector<double> test_vec{1,2,3,4,5};
py::list test_list = test_vec;
py::list test_list2(test_vec);
py::list test_list3 = py::cast<py::list>(test_vec);

And here are the errors:

error: conversion from ‘std::vector<double>’ to non-scalar type ‘pybind11::list’ requested
    py::list test_list = test_vec;
error: no matching function for call to ‘pybind11::list::list(std::vector<double>&)’
    py::list test_list2(test_vec);
error: no matching function for call to ‘cast(std::vector<double>&)’
    py::list test_list3 = py::cast<py::list>(test_vec)

The docs say to look in tests/test_stl.cpp for examples of how this should work, however I'm afraid that I am having trouble deciphering what is happening in that file.

Hossein
  • 24,202
  • 35
  • 119
  • 224
Ben Farmer
  • 2,387
  • 1
  • 25
  • 44

1 Answers1

10

The conversion happens automatically for function arguments and return values that you create bindings for if you include pybind11/stl.h. You can also do it explicitly in C++ code like this:

#include <pybind11/stl.h>
// [...]
std::vector<double> test_vec{1, 2, 3, 4, 5};
py::list test_list3 = py::cast(test_vec);

Please bear in mind that this creates a copy, though.
For a different approach please refer to making-opaque-types and binding-stl-containers.

Hossein
  • 24,202
  • 35
  • 119
  • 224
ahans
  • 1,697
  • 12
  • 19
  • Can Pybin11 automatically bind `std::list<>` into a Python list? The examples in the documentation are only for `std::vector<>` and `std::map<>`. – TonySalimi Jul 10 '23 at 08:34
  • @TonySalimi I haven't tested it, but [this](https://github.com/pybind/pybind11/blob/v2.10.4/include/pybind11/stl.h#L221) indicates that `std::list` is supported (and also `std::deque`). So replacing `std::vector` in my example with either `std::list` or `std::deque` should work just as well. – ahans Jul 12 '23 at 06:49