开发者

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 开发者_C百科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 (i.e., 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜