Hossein
Hossein

Reputation: 25934

How to convert Python dict to the C++ counter part in Pybind11?

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

Answers (1)

Hossein
Hossein

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

Related Questions