我正在尝试用 const boost :: interprocess :: basic_string& 替换一个返回 const std :: string& 的类方法。我面临的主要挑战是两个类之间的不兼容性,尽管它们的实现相似。为了更清楚的解释,我将把它放入代码
class A
{ std::string m_str;
const std::string & StrVal() { return m_str; }
}
现在这个类看起来像这样:
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; }
}
问题在于我们拥有庞大的代码库,具体取决于此:
A a;
const std::string & str = a.StrVal();
// Many string specific operations go here, comparing str with other std::strings for instance
即使我使用const ShMemString&amp;替换所有代码替换预期结果,但是修复后续用法将是一项更加困难的工作。我很惊讶地发现boost的字符串不包含std :: string的任何比较/构造方法。
有关如何处理此事的任何想法?
答案 0 :(得分:2)
即使boost::interprocess::basic_string<>
确实转换为std::basic_string<>
,但对于您的目的来说也是完全无用的 - 转换后,进程间字符串将被销毁,而其 allocator是重要的一个(即,在共享内存中保存数据的那个,我假设这是你首先转换basic_string<>
实现的动机。)
所以,最后,你别无选择,只能用ShMemString const&
(或auto const&
替换预期结果代替所有代码,如果你的编译器足够支持它的话)。
为了让将来减轻痛苦,明智地typedef
:
struct A
{
typedef ShMemString StrValType;
StrValType const& StrVal() { return m_str; }
private:
StrValType m_str;
};
// ...
A a;
A::StrValType const& str = a.StrVal();
这样,只有typedef
内的A
需要更改,依赖它的所有代码都会自动使用正确的类型。
答案 1 :(得分:2)
问题在于我们拥有庞大的代码库,具体取决于此:
为什么第二个A::StrVal
会返回interprocess::basic_string
?它是内部使用A
的类interprocess::basic_string
的实现细节。它的接口使用的实际字符串类不必相同。这简直就是糟糕的重构。
A::StrVal
应该返回std::string
,就像往常一样(当然,不是const&
,但用户代码不需要因此而改变)。因此,A::StrVal
将需要在两种字符串类型之间进行转换。这就是如何进行适当的重构:您更改了实现,但接口保持不变。
是的,这意味着您将不得不复制字符串数据。和它一起生活。