diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9782887e8ac4221f47dea30a621894a38fcdc8c..e90917d1efbdbbcb4b5f821b3d0337a1f91f397b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 ### Fixed
 - Fix function signature on Windows ([#494](https://github.com/stack-of-tasks/eigenpy/pull/494))
 
+### Added
+- Add bp::dist to std::map converter ([#499](https://github.com/stack-of-tasks/eigenpy/pull/499))
+
 ## [3.8.1] - 2024-08-25
 
 ### Fixed
diff --git a/include/eigenpy/std-map.hpp b/include/eigenpy/std-map.hpp
index 9b010e900426ecd31849bcbd9cffd5c9b9e6e777..0d7123577b1a337f5aefe7fd372b6c8ec8209385 100644
--- a/include/eigenpy/std-map.hpp
+++ b/include/eigenpy/std-map.hpp
@@ -6,7 +6,13 @@
 #ifndef __eigenpy_utils_map_hpp__
 #define __eigenpy_utils_map_hpp__
 
+#include "eigenpy/pickle-vector.hpp"
+
+#include <boost/python/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/stl_iterator.hpp>
 #include <boost/python/suite/indexing/map_indexing_suite.hpp>
+#include <boost/python/to_python_converter.hpp>
+#include <map>
 
 namespace eigenpy {
 namespace details {
@@ -31,31 +37,165 @@ struct overload_base_get_item_for_std_map
     typename Container::iterator i = container.get().find(idx);
     if (i == container.get().end()) {
       PyErr_SetString(PyExc_KeyError, "Invalid key");
-      bp::throw_error_already_set();
+      boost::python::throw_error_already_set();
     }
 
-    typename bp::to_python_indirect<data_type&,
-                                    bp::detail::make_reference_holder>
+    typename boost::python::to_python_indirect<
+        data_type&, boost::python::detail::make_reference_holder>
         convert;
-    return bp::object(bp::handle<>(convert(i->second)));
+    return boost::python::object(boost::python::handle<>(convert(i->second)));
   }
 
   static index_type convert_index(Container& /*container*/, PyObject* i_) {
-    bp::extract<key_type const&> i(i_);
+    boost::python::extract<key_type const&> i(i_);
     if (i.check()) {
       return i();
     } else {
-      bp::extract<key_type> i(i_);
+      boost::python::extract<key_type> i(i_);
       if (i.check()) return i();
     }
 
     PyErr_SetString(PyExc_TypeError, "Invalid index type");
-    bp::throw_error_already_set();
+    boost::python::throw_error_already_set();
     return index_type();
   }
 };
 
 }  // namespace details
+
+///////////////////////////////////////////////////////////////////////////////
+// The following snippet of code has been taken from the header
+// https://github.com/loco-3d/crocoddyl/blob/v2.1.0/bindings/python/crocoddyl/utils/map-converter.hpp
+// The Crocoddyl library is written by Carlos Mastalli, Nicolas Mansard and
+// Rohan Budhiraja.
+///////////////////////////////////////////////////////////////////////////////
+
+namespace python {
+
+namespace bp = boost::python;
+
+/**
+ * @brief Create a pickle interface for the std::map
+ *
+ * @param[in] Container  Map type to be pickled
+ * \sa Pickle
+ */
+template <typename Container>
+struct PickleMap : public PickleVector<Container> {
+  static void setstate(bp::object op, bp::tuple tup) {
+    Container& o = bp::extract<Container&>(op)();
+    bp::stl_input_iterator<typename Container::value_type> begin(tup[0]), end;
+    o.insert(begin, end);
+  }
+};
+
+/// Conversion from dict to map solution proposed in
+/// https://stackoverflow.com/questions/6116345/boostpython-possible-to-automatically-convert-from-dict-stdmap
+/// This template encapsulates the conversion machinery.
+template <typename Container>
+struct dict_to_map {
+  static void register_converter() {
+    bp::converter::registry::push_back(&dict_to_map::convertible,
+                                       &dict_to_map::construct,
+                                       bp::type_id<Container>());
+  }
+
+  /// Check if conversion is possible
+  static void* convertible(PyObject* object) {
+    // Check if it is a list
+    if (!PyObject_GetIter(object)) return 0;
+    return object;
+  }
+
+  /// Perform the conversion
+  static void construct(PyObject* object,
+                        bp::converter::rvalue_from_python_stage1_data* data) {
+    // convert the PyObject pointed to by `object` to a bp::dict
+    bp::handle<> handle(bp::borrowed(object));  // "smart ptr"
+    bp::dict dict(handle);
+
+    // get a pointer to memory into which we construct the map
+    // this is provided by the Python runtime
+    typedef bp::converter::rvalue_from_python_storage<Container> storage_type;
+    void* storage = reinterpret_cast<storage_type*>(data)->storage.bytes;
+
+    // placement-new allocate the result
+    new (storage) Container();
+
+    // iterate over the dictionary `dict`, fill up the map `map`
+    Container& map(*(static_cast<Container*>(storage)));
+    bp::list keys(dict.keys());
+    int keycount(static_cast<int>(bp::len(keys)));
+    for (int i = 0; i < keycount; ++i) {
+      // get the key
+      bp::object keyobj(keys[i]);
+      bp::extract<typename Container::key_type> keyproxy(keyobj);
+      if (!keyproxy.check()) {
+        PyErr_SetString(PyExc_KeyError, "Bad key type");
+        bp::throw_error_already_set();
+      }
+      typename Container::key_type key = keyproxy();
+
+      // get the corresponding value
+      bp::object valobj(dict[keyobj]);
+      bp::extract<typename Container::mapped_type> valproxy(valobj);
+      if (!valproxy.check()) {
+        PyErr_SetString(PyExc_ValueError, "Bad value type");
+        bp::throw_error_already_set();
+      }
+      typename Container::mapped_type val = valproxy();
+      map[key] = val;
+    }
+
+    // remember the location for later
+    data->convertible = storage;
+  }
+
+  static bp::dict todict(Container& self) {
+    bp::dict dict;
+    typename Container::const_iterator it;
+    for (it = self.begin(); it != self.end(); ++it) {
+      dict.setdefault(it->first, it->second);
+    }
+    return dict;
+  }
+};
+
+/**
+ * @brief Expose an std::map from a type given as template argument.
+ *
+ * @param[in] T          Type to expose as std::map<T>.
+ * @param[in] Compare    Type for the Compare in std::map<T,Compare,Allocator>.
+ * @param[in] Allocator  Type for the Allocator in
+ * std::map<T,Compare,Allocator>.
+ * @param[in] NoProxy    When set to false, the elements will be copied when
+ * returned to Python.
+ */
+template <class Key, class T, class Compare = std::less<Key>,
+          class Allocator = std::allocator<std::pair<const Key, T> >,
+          bool NoProxy = false>
+struct StdMapPythonVisitor
+    : public bp::map_indexing_suite<
+          typename std::map<Key, T, Compare, Allocator>, NoProxy>,
+      public dict_to_map<std::map<Key, T, Compare, Allocator> > {
+  typedef std::map<Key, T, Compare, Allocator> Container;
+  typedef dict_to_map<Container> FromPythonDictConverter;
+
+  static void expose(const std::string& class_name,
+                     const std::string& doc_string = "") {
+    namespace bp = bp;
+
+    bp::class_<Container>(class_name.c_str(), doc_string.c_str())
+        .def(StdMapPythonVisitor())
+        .def("todict", &FromPythonDictConverter::todict, bp::arg("self"),
+             "Returns the std::map as a Python dictionary.")
+        .def_pickle(PickleMap<Container>());
+    // Register conversion
+    FromPythonDictConverter::register_converter();
+  }
+};
+
+}  // namespace python
 }  // namespace eigenpy
 
 #endif  // ifndef __eigenpy_utils_map_hpp__
diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt
index a65ac2e0287aec6c051f07e046c959a37ee3729a..2c1eec31b35a58ef3927ede297b7619d4b60025c 100644
--- a/unittest/CMakeLists.txt
+++ b/unittest/CMakeLists.txt
@@ -56,6 +56,7 @@ endif()
 add_lib_unit_test(std_vector)
 add_lib_unit_test(std_array)
 add_lib_unit_test(std_pair)
+add_lib_unit_test(std_map)
 add_lib_unit_test(user_struct)
 
 if(CMAKE_CXX_STANDARD GREATER 14 AND CMAKE_CXX_STANDARD LESS 98)
@@ -155,6 +156,8 @@ add_python_eigenpy_lib_unit_test("py-std-vector"
 
 add_python_lib_unit_test("py-std-array" "unittest/python/test_std_array.py")
 
+add_python_lib_unit_test("py-std-map" "unittest/python/test_std_map.py")
+
 add_python_lib_unit_test("py-std-pair" "unittest/python/test_std_pair.py")
 
 add_python_lib_unit_test("py-user-struct" "unittest/python/test_user_struct.py")
diff --git a/unittest/python/test_std_map.py b/unittest/python/test_std_map.py
new file mode 100644
index 0000000000000000000000000000000000000000..091027b21b063eb3cfe0e33659a5fc7e96096943
--- /dev/null
+++ b/unittest/python/test_std_map.py
@@ -0,0 +1,6 @@
+from std_map import copy, std_map_to_dict
+
+t = {"one": 1.0, "two": 2.0}
+
+assert std_map_to_dict(t) == t
+assert std_map_to_dict(copy(t)) == t
diff --git a/unittest/std_map.cpp b/unittest/std_map.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5997e39cc82df6deb68ceb355e3613c2cb122b83
--- /dev/null
+++ b/unittest/std_map.cpp
@@ -0,0 +1,35 @@
+/// @file
+/// @copyright Copyright 2023 CNRS INRIA
+
+#include <eigenpy/eigenpy.hpp>
+#include <eigenpy/std-map.hpp>
+#include <iostream>
+
+namespace bp = boost::python;
+
+template <typename T1>
+bp::dict std_map_to_dict(const std::map<std::string, T1>& map) {
+  bp::dict dictionnary;
+  for (auto const& x : map) {
+    dictionnary[x.first] = x.second;
+  }
+  return dictionnary;
+}
+
+template <typename T1>
+std::map<std::string, T1> copy(const std::map<std::string, T1>& map) {
+  std::map<std::string, T1> out = map;
+  return out;
+}
+
+BOOST_PYTHON_MODULE(std_map) {
+  eigenpy::enableEigenPy();
+
+  eigenpy::python::StdMapPythonVisitor<
+      std::string, double, std::less<std::string>,
+      std::allocator<std::pair<const std::string, double> >,
+      true>::expose("StdMap_Double");
+
+  bp::def("std_map_to_dict", std_map_to_dict<double>);
+  bp::def("copy", copy<double>);
+}