Reputation: 25934
Currently I'm trying to convert a py::dict
into its counterpart C++
s std::map
. Trying to use the
automatic conversion like this fails :
#include <pybind11/stl.h>
namespace py = pybind11;
using namespace py::literals;
...
py::dict py_kwargs = py::dict("number1"_a = 5, "number2"_a = 42);
auto cpp_kwargs = py_kwargs.cast<std::map<int, int>>();
with an exception stating :
Unable to cast Python instance of type <class 'dict'> to C++ type 'std::map<int,int,std::less<int>,std::allocator<std::pair<int const ,int> > >'
What am I missing here?
Also on a side note, how should I go about the situation , where the python dictionary has different key types, for example like :
py::dict py_kwargs = py::dict("name"_a = "World", "number"_a = 42);
How should I go about the conversion in such cases?
Upvotes: 6
Views: 5165
Reputation: 25934
OK, I found the issue, before that I ended up doing the conversion like this :
map<std::string, int> convert_dict_to_map(py::dict dictionary)
{
map<std::string, int> result;
for (std::pair<py::handle, py::handle> item : dictionary)
{
auto key = item.first.cast<std::string>();
auto value = item.second.cast<int>();
//cout << key << " : " << value;
result[key] = value;
}
return result;
}
and then, looked carefully at the :
auto cppmap = kwargs.cast<map<int, int>>();
and finally noticed my issue. it should have been :
auto cppmap = kwargs.cast<map<std::string, int>>();
I made a mistake, when I changed my example dict and later on reverted back the changes but forgot to change the signature!
Anyway, it seems the first solution may be a better choice, as it allows the developer to work with Python
's dynamic nature better.
That is, a Python
dictionary may very well, include different pairs (such as string:string
, string:int
, int:float
, etc all in the same dictionary object). Therefore, making sure the items are validly reconstructed in c++ can be done much better using the first crude method!
Upvotes: 5