6

Is there a simple way to do this? I've tried the following:

typedef allocator<char,managed_shared_memory::segment_manager>
    CharAllocator;
typedef boost::container::basic_string<char, std::char_traits<char>, CharAllocator>
    my_basic_string;

std::string s(my_basic_string);
wizurd
  • 3,541
  • 3
  • 33
  • 50
  • What is `my_basic_string`? We can't answer this if you don't specify that. I can _assuming_ a `boost::container::basic_string, boost::interprocess::allocator >` or similar, but if e.g. `char` doesn't match, there's gonna be much more conversion logic – sehe Jun 18 '15 at 07:59
  • @sehe : Updated to show what my_basic_string is... – wizurd Jun 18 '15 at 13:55

3 Answers3

8

As @T.C. has said, you should use:

std::string s(my_basic_string.data(), my_basic_string.size());

or

std::string s(my_basic_string.begin(), my_basic_string.end());

I prefer the second, but both will work.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45
1

Just copy element-wise (which any decent standard library implementation optimizes into memcpy):

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;
typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef boost::container::basic_string<char, std::char_traits<char>, CharAllocator> my_shared_string;

std::string s(my_shared_string const& ss) {
    return std::string(ss.begin(), ss.end());
}

I called the string "my_shared_string" (because it's not any more "basic" than std::string). In fact it's good to notice this has everything to do with containers with custom allocators, and nothing with std::string or Boost Interprocess in particular:

typedef std::basic_string<char, std::char_traits<char>, CharAllocator> my_shared_string;

behaves exactly the same for the given problem; So does e.g.:

typedef std::vector<char, CharAllocator> my_shared_vector;

std::vector<char> v(my_shared_vector const& ss) {
    return std::vector<char>(ss.begin(), ss.end());
}
sehe
  • 374,641
  • 47
  • 450
  • 633
0

Changed according to comments from @T.C.

You may use this:

std::string s(my_basic_string.c_str(), my_basic_string.size());
Bin Li
  • 7
  • 5
  • Assuming no embedded nulls. Otherwise the dual-iterator or the pointer-and-length constructor should be used. – T.C. Jun 17 '15 at 23:33
  • Thanks T.C for your comments. But I don't understand your meaning, could you please provide a simple example? – Bin Li Jun 17 '15 at 23:44
  • If the string contained in `my_basic_string` has an embedded null character - `"abc\0def"`, for instance - then your code will initialize `s` to `"abc"` only since it stops at the first null character. – T.C. Jun 18 '15 at 00:24
  • @T.C. Thanks for example. But for a basic_string with "abc\0def", what's the meaning of "def"? When use the basic_string, i.e. my_basic_string.c_str(), my_basic_string.data(), my_basic_string.size(), all ignore the def. Please refer to my example: [link](http://coliru.stacked-crooked.com/a/c87c414a84b1f0c1) – Bin Li Jun 18 '15 at 02:56
  • You are seeing the same issue here - if you use constructor taking a `const char *`, it's going to assume that the string terminates at the first null character it encounters. You need to [pass the length explicitly](http://coliru.stacked-crooked.com/a/3b856ac5602cd6c4). – T.C. Jun 18 '15 at 03:01