title: Extracting from wrapper to map of vector
body: <p>The context is that of an embedded python script and calling the interpreter
  from a code written in C++. </p>
  
  <p>The C++ and Python codes below summarise the techniques to wrap in C++, use in Python and then extract back in C++ the two most common STL containers:</p>
  
  <ul>
  <li>std::vector</li>
  <li>std::map</li>
  </ul>
  
  <p>It focuses more particularly on the case when they hold std::string type elements. </p>
  
  <p>One of the difficulties here for coders unfamiliar with the boost python library is that the boost iterators and iterable suites are mapping a concept which is common to both languages but which nonetheless is treated fairly differently in the two respective programming environments. </p>
  
  <p>Drawing on existing material and personal experiments, I have clarified to myself what seems to be the intended way for the most common usage. Nothing that has not been shown elsewhere but it does feel as though boost::python can tolerate a bit of redundancy in terms of examples and illustrating cases.</p>
  
  <p>There is one case that I do not seem to be able to solve so far: returning a wrapped vector of strings to C++. I would appreciate it if someone could enlight me on this. </p>
  
  <p>The code is intended to be self-contained and serves two purposes. Firstly, it is meant to help people who, like myself, are looking for more examples of simple use cases. It also shows that manipulating a vector of double is more straight-forward than a vector string. </p>
  
  <p>In the C++ example below I get a run-time error saying essentially:
  typedef std::vector VecStr;
  class boost::python::class> struct boost::python::deltail::not_specified_struc from this Python object of typeMapStringVectorString. </p>
  
  <p>Any suggestion would be appreciated. </p>
  
  <p>PS: I had to reconstruct the amended code from memory and there might be some syntax errors. I correct them as soon as I have access to connected machine. </p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;boost/python.hpp&gt;
  #include &lt;boost/python/suite/indexing/vector_indexing_suite.hpp&gt;
  #include &lt;boost/python/suite/indexing/map_indexing_suite.hpp&gt;
  #include &lt;Python.h&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  #include &lt;vector&gt;
  
  using namespace std;
  using namespace boost::python;
  
  BOOST_PYTHON_MODULE(idctor)
  {
      typedef std::vector&lt;string&gt; VectorString;
      typedef std::map&lt;string, VectorString&gt; MapVectorString;
      typedef class_&lt;VectorString, shared_ptr&lt;VectorString&gt;&gt; pyVectorString;
      using namespace boost::python;
      class_&lt;std::vector&lt;double&gt; &gt;("DoubleVector")
          .def(vector_indexing_suite&lt;std::vector&lt;double&gt; &gt;());
  
      class_&lt;std::vector&lt;std::string&gt;,shared_ptr&lt;VectorString&gt; &gt;("VectorString")
          .def(vector_indexing_suite&lt;std::vector&lt;string&gt; &gt;());
  
      class_&lt;std::map&lt;std::string, double&gt; &gt;("StringDoubleMap")
          .def(map_indexing_suite&lt;std::map&lt;std::string, double&gt; &gt;());
  
      class_&lt;std::map&lt;string, string&gt; &gt;("MapStringString")
          .def(map_indexing_suite&lt;std::map&lt;std::string, string&gt; &gt;());
  
      class_&lt;std::map&lt;string, VectorString&gt; , shared_ptr&lt;MapVectorString&gt;&gt;("MapStringVectorString")
          .def(map_indexing_suite&lt;std::map&lt;std::string, VectorString&gt; &gt;());
  }
  
  
  typedef std::vector&lt;string&gt; VectorString;
  typedef  class_&lt;VectorString&gt; pyVectorString;
  typedef class_&lt;VectorString, shared_ptr&lt;VectorString&gt;&gt; pyMapVectorString;
  
  
  int main()
  {
      PyImport_AppendInittab("idctor", &amp;PyInit_idctor);
      Py_Initialize();
      try {
  
          //PyInit_hello();
          object main
              = object(handle&lt;&gt;(borrowed(PyImport_AddModule("__main__"))));
          object main_namespace = main.attr("__dict__");
          PyRun_SimpleString("import sys\n");
          exec_file("G:\\Developments\\VisualStudio\\BoostPythonSTLContainers\\stlcontainers.py", main_namespace);
          //       Getting back an Python object containing a 
          //            vector of double, extracting the 
          //            corresponding typed C++ object and using it
          object pyv = main_namespace["v"];
          //----------------&gt;  this works &lt;--------------
          std::vector&lt;double&gt;&amp; v = extract&lt;vector&lt;double&gt;&amp;&gt;(pyv);
          v.push_back(665);
          //----------------&gt; this does not &lt;----------------
          //       Getting back a working Python object 
          object pyvs = main_namespace["vs"];
          //   Attempting to convert it back to its true C++ type
          //    Here the conversion fails:
          VectorString&amp; vs = extract&lt;VectorString&amp;&gt;(pyvs);
          vs.push_back("not yet the beast");
  
          //   Attempt to do the same with a map of string to vector of strings
          object pymvs = main_namespace["mvs"];
  
          //----------------&gt; Clearly this fails too &lt;--------------
          pyMapVectorString&amp; mvs = extract&lt;pyMapVectorString&amp;&gt;(pymvs);
          object pyvs = mvs["this "];
          VectorString&amp; vs = extract&lt;VectorString&amp;&gt;(pyvs);
          vs.push_back({ "should ","work" });
      }
      catch (error_already_set) {
          PyErr_Print();
          return 1;
      }
  
      Py_Finalize();
      return 0;
  }
  </code></pre>
  
  <p>and here is the (working) python code:</p>
  
  <pre><code># 
  #    All the python code below is working fine
  #         (the issue is converting back in C++)
  import idctor
  #defining a function to print a container
  def tostr(container):
      string ='['
      for i in container:
          string += str(i)+","
      string+='end]'
      return string
  
  # Turning it into a instance method
  idctor.DoubleVector.__str__ = tostr
  
  # instantiating a vector of doubles
  v = idctor.DoubleVector()
  v.append(1.0)
  v.append(2.0)
  for i in v:
      print(i)
  
  #instantiating a vector of strings
  idctor.VectorString.__str__ = tostr
  vs = idctor.VectorString()
  vs.append("he2")
  vs.append("he1")
  print("Directly: ", vs)
  for s in vs:
      print(s)
  m = idctor.StringDoubleMap()
  
  # instantiating a map of string to doubles
  m["a"] = 1
  m["b"] = 2
  for i in m:
      print(i)
  print(m)
  
  #instantiating a map of string to strings
  ms = idctor.MapStringString()
  ms["a"]="he1"
  ms["b"]="he2"
  for s in ms:
      print(s)
  
  #instantiating a map of string to vectors of strings
  mvs = idctor.MapStringVectorString()
  mvs["a"]=vs 
  vs2=idctor.VectorString()
  vs2.append("cy")
  vs2.append("ve")
  mvs["b"]=vs2
  for vs in mvs:
      print(vs)
  </code></pre>