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.