Disclaimer: yes, I do know about boost::python::map_indexing_suite.
Task: I have a C++ class which I want to wrap with Boost.Python. Its constructor takes a std::map argument. Here is the C++ header:
// myclass.hh
typedef std::map<int, float> mymap_t;
class MyClass {
public:
explicit MyClass(const mymap_t& m);
// ...
};
// ...
Here is the Boost.Python wrapper (essential parts only):
// myclasswrapper.cc
#include "mymap.hh"
#include "boost/python.hpp"
#include "boost/python/suite/indexing/map_indexing_suite.hpp"
namespace bpy = boost::python;
// wrapping mymap_t
bpy::class_<mymap_t>("MyMap")
.def(bpy::map_indexing_suite<mymap_t>())
;
// wrapping MyClass
bpy::class_<MyClass>("MyClass", "My example class",
bpy::init<mymap_t>() // ??? what to put here?
)
// .def(...method wrappers...)
;
This compiles. However, I cannot create the mapped MyClass object from the Python side because I don't know what to pass as argument to the constructor. Dictionaries do not get converted to std::map-s automatically:
# python test
myclass = MyClass({1:3.14, 5:42.03})
the interpreter complains (rightly so):
Boost.Python.ArgumentError: Python argument types in
MyClass.__init__(MyClass, dict)
did not match C++ signature:
__init__(_object*, std::__1::map<int, float, ...
and MyMap on the Python side cannot be initialised with a dictionary either.
Having googled away the best part of a day, I could find only examples for "normal" methods taking std::map arguments that are mapped with .def(...). And in .def(...) you do not have to specify explicitly the arguments of the mapped method, they are magically discovered. With constructors you must use boost::python::init<...>(), or at least that is what I understood from the docs.
Questions:
- Shall I add something to the
MyMapwrapper to helpmap_indexing_suiteconvert from a Python dictionary? - Shall I use a different template argument in
boost::python::init<...>in theMyClasswrapper? - Any other ideas...?
Note: I have also seen this accepted answer at SO, then I scrolled down and read the comment by @YvesgereY:
"For the record, map_indexing_suite solution doesn't work, since no implicit "dict->std::map" from_python converter will be applied."
And I lost faith :-)