在C++中使用不同的分配器复制对象
Copying objects using different allocators in C++
所以我有一个很好的持久分配器类persistent_alloc<T>
,它允许我在持久内存中分配C++容器对象和字符串,该内存由mmaped文件支持,该文件可以从我的程序的一次运行持续到下一次运行。
当我想做任何混合持久和非持久对象的事情时,我的问题就来了。 例如,我有
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;
}
。现在我可以比较字符串的相等性。 但是为每个操作添加这些似乎很痛苦 - 似乎它们应该由标准库提供。 更糟糕的是,赋值运算符和复制构造函数必须是成员,不能像这样定义为全局内联函数。
有没有合理的方法可以做到这一点? 还是我必须有效地重写整个标准库以有效地支持分配器?
有一种方法可以解决这个问题,但你需要跳出框框思考一下。您需要的是一个中间类型,它可以从std::string
和分配器字符串隐式构造。
目前,C++委员会面前有一个关于这样的事情的提案。它基于已经存在的Google构建的Apache许可实现。它叫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
的一部分,那就太好了,这样你就不需要解决方法了。但事实并非如此。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 使用不兼容的分配器复制分配无序列图
- 从标准容器重新绑定和复制分配器
- C++ 如何在容器类复制构造函数中复制分配器对象
- 在分配器感知类调用复制构造函数中对向量元素的引用
- 复制有状态分配器:标准库分配器语义和内部内存
- 当涉及分配器时,是否有类似于复制和交换习惯用法的东西
- 为什么要求自定义分配器是可复制的
- 在C++中使用不同的分配器复制对象
- 为什么c++中的分配器需要复制构造函数
- 如果分配器提供realloc语义,std::vector是否可以避免复制
- STL分配器复制构造函数需求的目的是什么?