简体   繁体   中英

boost::interprocess::basic_string as std::string

I am trying to replace a class method which returns const std::string & with const boost::interprocess::basic_string & . The main challenge I am facing is the incompatibility between the two classes despite their implementation similarity. For more clear explanation I will put that into code

class A
{ std::string m_str;
 const std::string & StrVal() { return m_str; }
}

Now this class has to look like this:

typedef boost::interprocess::allocator<char,boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocatorChar;
typedef boost::interprocess::basic_string<char, std::char_traits<char>,ShmemAllocatorChar> ShMemString;

class A
{
 ShMemString m_str;
 const ShMemString & StrVal() { return m_str; }
}

The problem is that we have a huge code base depending on this:

A a;
const std::string & str = a.StrVal();
// Many string specific operations go here, comparing str with other std::strings for instance

Even If I go over all the code replacing the expected results with const ShMemString &, it will be an even harder work to also fix the uses that follow. I was surprised to find out that the boost's string does not include any comparison/construction methods from std::string.

Any ideas on how to approach this?

Even if boost::interprocess::basic_string<> did have a conversion to std::basic_string<> , it would be completely useless for your purposes -- after the conversion, the interprocess string would be destroyed, and its allocator is the important one (ie, the one holding the data in shared memory, which I assume is your motivation for switching basic_string<> implementations in the first place).

So, in the end, you have no choice but to go over all the code replacing the expected results with ShMemString const& (or auto const& if your compiler is recent enough to support it).


To make this less painful in the future, typedef judiciously:

struct A
{
    typedef ShMemString StrValType;
    StrValType const& StrVal() { return m_str; }
private:
    StrValType m_str;
};

// ...

A a;
A::StrValType const& str = a.StrVal();

This way, only the typedef inside of A needs to change and all code relying on it will automatically use the correct type.

The problem is that we have a huge code base depending on this:

Why does A::StrVal in the second one return an interprocess::basic_string ? It is an implementation detail of the class A that it uses interprocess::basic_string internally. The actual string class it's interface uses does not have to be the same. This is simply poor refactoring.

A::StrVal should return a std::string , just like always (well, not a const& of course, but user code won't need to change because of that). And therefore, A::StrVal will need to do the conversion between the two string types. That's how proper refactoring is done: you change the implementation, but the interface stays the same.

Yes, this means you're going to have to copy the string data. Live with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM