所以我有一个很好的持久化分配器类persistent_alloc<T>
,它允许我在持久性内存中分配C ++容器对象和字符串,该内存由一个mmaped文件支持,该文件可以从我的程序的一次运行到下一次运行。 / p>
当我想做任何混合持久和非持久对象的事情时,我的问题就来了。例如,我有
typedef std::basic_string<char, std::char_traits<char>, persistent_alloc<char>> pstring;
pstring a, b, c;
std::string x, y, z;
我希望能够做到这样的事情:
if (a == x)
a = y;
c = z + b;
依此类推,但默认情况下它不起作用,因为pstring
和std::string
是不相关的类型。现在就比较而言,我可以定义:
template<typename Alloc1, typename Alloc2> inline bool
operator==(const std::basic_string<char, std::char_traits<char>, Alloc1> &a,
const std::basic_string<char, std::char_traits<char>, Alloc2> &b)
{
return strcmp(a.c_str(), b.c_str()) == 0;
}
...现在我可以比较字符串的相等性。但是为每个操作添加这些操作似乎很痛苦 - 似乎它们应该由标准库提供。更糟糕的是,赋值运算符和复制构造函数必须是成员,不能像这样定义为全局内联函数。
有合理的方法吗?或者我是否必须有效地重写整个标准库以有效地支持分配器?
答案 0 :(得分:7)
有一种方法可以解决这个问题,但你需要在盒子外思考一下。您需要的是一个可以从std::string
和您的分配器字符串隐式构造的中间类型。
有一个proposal for such a thing before the C++ committee currently。它基于Google-built Apache-licensed implementation that already exists。它被称为basic_string_ref
;它是一个模板类,它基本上是指向字符串中第一个字符的指针和一个表示字符串长度的大小。它不是一个真正的容器,因为它不管理内存。
这正是您所需要的。
basic_string_ref
对于特定字符类型和特征类型,可以从std::basic_string
隐式构造,而不管分配器。
所有比较运算符都可以用basic_string_ref
来定义。由于它可以从std::basic_string
隐式构造(并且几乎可以自由构造),因此它可以透明地用于不同分配字符串之间的比较。
做任务相当棘手,但可行。它需要一系列转换:
a = pstring{basic_string_ref{y}};
当然不是最漂亮的代码。我们更愿意简单地将std::basic_string
的复制构造函数和赋值运算符更改为分配器不可知。但由于这不可行,这真的是下一个最好的事情。你甚至可以将它包装在模板函数中:
template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
return std::basic_string<charT, traits, DestAllocator>{basic_string_ref<charT, traits>{y}};
}
当然,如果你能做到这一点,你可以这样做:
template<typename DestAllocator, typename SourceAllocator, typename charT, typename traits>
std::basic_string<charT, traits, DestAllocator> conv_str(const std::basic_string<charT, traits, SourceAllocator> &input)
{
return std::basic_string<charT, traits, DestAllocator>{y.begin(), y.end()};
}
如果这只是std::basic_string
的一部分,那就太棒了,所以你不需要解决方法。但事实并非如此。