4

我正在尝试用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 & 替换了预期结果的所有代码,也修复以下用途将是一项更加艰巨的工作。我惊讶地发现 boost 的字符串不包含来自 std::string 的任何比较/构造方法。

关于如何解决这个问题的任何想法?

4

2 回答 2

2

即使boost::interprocess::basic_string<>确实有转换为std::basic_string<>,它对您的目的也完全没用——在转换之后,进程间字符串将被销毁,它的分配器是重要的分配器(即,将数据保存在共享内存中的分配器,我假设是您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需要改变,所有依赖它的代码都会自动使用正确的类型。

于 2011-09-16T16:56:18.430 回答
2

问题是我们有一个庞大的代码库,这取决于:

为什么A::StrVal在第二个返回一个interprocess::basic_string?它是它在内部A使用的类的实现细节。interprocess::basic_string它的接口使用的实际字符串类不必相同。这简直是​​糟糕的重构。

A::StrVal应该std::string像往常一样返回 a (const&当然,不是 a,但用户代码不需要因此而更改)。因此,A::StrVal需要在两种字符串类型之间进行转换。这就是正确重构的方式:您更改了实现,但接口保持不变。

是的,这意味着您将不得不复制字符串数据。忍受它。

于 2011-09-16T20:58:21.107 回答