I'm creating a map (from string to string in this example) in shared memory using Boost.Interprocess. The compiler seems to want to force me, during retrieval from the map, to allocate memory in the managed segment just to (unnecessarily) contain the query term.
I'd like to be able
to look up values in a shared map more efficiently, by matching the map's keys against instances that are already in non-shared memory, without performing this extra allocation.  But it's
refusing to compile if I try to use a std::string or const char * as the argument to the map's find method.
(see compiler error messages at bottom).
Do I need to define some sort of
comparator method between my shared-memory key type and its non-shared equivalent (std::string in this example)? If so, what should
this look like and how should I make the map use it?   If not, what should I do?
Here's the code, followed by the compiler errors.  The problem is towards the bottom of main().
// shmap2.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
//Typedefs of allocators and containers
namespace Shared
{
    typedef boost::interprocess::managed_shared_memory
        Segment;
    typedef boost::interprocess::managed_shared_memory::segment_manager
        SegmentManager;
    typedef boost::interprocess::allocator< void, SegmentManager >
        Allocator;
    typedef boost::interprocess::allocator< char, SegmentManager >
        CharAllocator;
    typedef boost::interprocess::basic_string< char, std::char_traits< char >, CharAllocator > 
        String;
    typedef std::less< String >
        StringComparator;
    // Definition of the shared map from String to String
    // (To avoid confusion, let's strictly use Python-like definitions of "key", "value" and "item")
    typedef std::pair< const String, String >
        MapItem;
    typedef boost::interprocess::allocator< MapItem, SegmentManager >
        MapItemAllocator;
    typedef boost::interprocess::map< String, String, StringComparator, MapItemAllocator >
        Map;
}
int main( void )
{
    struct shm_remove
    {
        shm_remove() { boost::interprocess::shared_memory_object::remove( "MySharedMemory" ); }
        ~shm_remove(){ boost::interprocess::shared_memory_object::remove( "MySharedMemory" ); }
    } remover;
    // Create shared memory
    Shared::Segment seg( boost::interprocess::create_only, "MySharedMemory", 65536 );
    // An allocator instance that can be converted to any allocator< T, Shared::SegmentManager > type
    Shared::Allocator alloc( seg.get_segment_manager() );
    // An instance of the string comparator, to construct the map
    Shared::StringComparator cmp;
    // Construct the shared memory map
    Shared::Map * myMapPtr = seg.construct< Shared::Map >( "myMap" )( cmp, alloc );
    // Here's the problem:
    // std::string key( "foo" );            // Compilation fails if you use this.
    // char key[] = "foo";                  // Compilation fails if you use this.
    Shared::String key( "foo", alloc );     // This the only version I can get to work.
                                            // But it forces you to create a copy of
                                            // the key you are searching for, in
                                            // the managed segment.
    // This is the point of the exercise:
    Shared::Map::iterator it = myMapPtr->find( key );
    return 0;
}
With a std::string as the key:
$ g++ -o shmap2 -D BOOST_ALL_NO_LIB  -I ../boost_1_57_0  shmap2.cpp
shmap2.cpp:79:40: error: no matching member function for call to 'find'
                Shared::Map::iterator it = myMapPtr->find( key );
                                           ~~~~~~~~~~^~~~
../boost_1_57_0/boost/container/detail/tree.hpp:1089:13: note: candidate function not
      viable: no known conversion from 'std::string' (aka 'basic_string<char,
      char_traits<char>, allocator<char> >') to 'const key_type' (aka 'const
      boost::container::basic_string<char, std::__1::char_traits<char>,
      boost::interprocess::allocator<char, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> >
      >') for 1st argument
   iterator find(const key_type& k)
            ^
../boost_1_57_0/boost/container/detail/tree.hpp:1092:19: note: candidate function not
      viable: no known conversion from 'std::string' (aka 'basic_string<char,
      char_traits<char>, allocator<char> >') to 'const key_type' (aka 'const
      boost::container::basic_string<char, std::__1::char_traits<char>,
      boost::interprocess::allocator<char, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> >
      >') for 1st argument
   const_iterator find(const key_type& k) const
                  ^
1 error generated.
With const char * as the key:
$ g++ -o shmap2 -D BOOST_ALL_NO_LIB  -I ../boost_1_57_0  shmap2.cpp
In file included from shmap2.cpp:17:
In file included from ../boost_1_57_0/boost/interprocess/containers/string.hpp:19:
../boost_1_57_0/boost/container/string.hpp:676:59: error: no matching constructor for
      initialization of 'allocator_type' (aka 'boost::interprocess::allocator<char,
      boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> >')
   basic_string(const CharT* s, const allocator_type& a = allocator_type())
                                                          ^
shmap2.cpp:79:46: note: in instantiation of default function argument expression for
      'basic_string<char, std::__1::char_traits<char>, boost::interprocess::allocator<char,
      boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >'
      required here
                Shared::Map::iterator it = myMapPtr->find( key );
                                                           ^
../boost_1_57_0/boost/interprocess/allocators/allocator.hpp:140:4: note: candidate
      constructor template not viable: requires single argument 'other', but no
      arguments were provided
   allocator(const allocator<T2, SegmentManager> &other)
   ^
../boost_1_57_0/boost/interprocess/allocators/allocator.hpp:129:4: note: candidate
     constructor not viable: requires single argument 'segment_mngr', but no arguments
     were provided
   allocator(segment_manager *segment_mngr)
   ^
../boost_1_57_0/boost/interprocess/allocators/allocator.hpp:134:4: note: candidate
     constructor not viable: requires single argument 'other', but no arguments were
     provided
   allocator(const allocator &other)
   ^
1 error generated.
UPDATE: following the suggestion of sehe, below, I tried replacing
typedef std::less< String >
    StringComparator;
with
typedef struct
{
    template< typename T, typename U >
    bool operator()( const T & t, const U & u )
        const { return t < u; }
} StringComparator;
but got the same two compiler errors.