复制有状态分配器:标准库分配器语义和内部内存
Copy stateful allocator: standard library allocator semantics and internal memory
我正在编写一个分配器集合,目的是在非常高性能的环境中使用它们,因此需要一点限制使用(由编译器而非运行时错误介导)。我一直在阅读有状态分配器的C++11语义,以及一致容器应该如何使用它们。
我粘贴了一个简单的分配器,它下面只包含分配器对象中的一块内存。在C++03中,这是非法的。
template <typename T, unsigned N>
class internal_allocator {
private:
unsigned char storage[N];
std::size_t cursor;
public:
typedef T value_type;
internal_allocator() : cursor(0) {}
~internal_allocator() { }
template <typename U>
internal_allocator(const internal_allocator<U>& other) {
// FIXME: What are the semantics here?
}
T* allocate(std::size_t n) {
T* ret = static_cast<T*>(&storage[cursor]);
cursor += n * sizeof(T);
if (cursor > N)
throw std::bad_alloc("Out of objects");
return ret;
}
void deallocate(T*, std::size_t) {
// Noop!
}
};
在C++11中,这可行吗复制有状态分配器意味着什么由于目标容器为源容器中的所有元素调用复制构造函数,所以分配器内部的内存必须显式复制,或者默认构造足够吗?
这就引出了一个问题,给定性能作为最终目标,propagate_on_container_
{copy
,swap
,move
}的合理值是什么?select_on_container_copy_construction
返回什么?
我很乐意根据要求提供更多细节,因为这似乎是一个相当模糊的问题——至少对我来说=)
这种争论源于这样的定义,即当a == b
为相同Allocator
类型的两个实例返回true
时,可以保证分配有a
的内存可以与b
解除分配。对于这个分配器来说,这似乎从来都不是真的。该标准还规定,当复制构造分配器时,如在A a(b)
中,a == b
保证返回true。
分配器要求分配器的副本必须能够释放彼此的内存,因此通常不可能将内存存储在分配器对象中。
这必须有效:
using IAllocChar = internal_allocator<char, 1024>;
IAllocChar::pointer p
IAllocChar a1;
{
IAllocChar a2(a1);
p = std::allocator_traits<IAllocChar>::allocate(a2, 1);
}
std::allocator_traits<IAllocChar>::deallocate(a1, p, 1)
因此,您需要将实际内存存储在分配器对象之外(或者只以非常有限的方式使用它,以确保对象在引用其拥有的内存时不会超出范围)。
您还将在重新绑定internal_allocator
时遇到困难,下面应该怎么做?
using IAllocChar = internal_allocator<char, 1024>;
using IAllocInt = std::allocator_traits<IAllocChar>::rebind_alloc<int>;
IAllocChar ac;
auto pc = ac.allocate(1); // got bored typing allocator_traits ;-)
IAllocInt ai(ac);
auto pi = ai.allocate(1);
IAllocChar(ai).deallocate(pc, 1);
IAllocInt(ac).deallocate(pi, 1);
相关文章:
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- Boost Spirit,获取迭代器内部语义动作
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 可以使用移动语义更改或改进此C++代码吗?
- 将 std::allocate_shared 与多态资源分配器一起使用
- c++在使用指针时移动语义
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 在C++17中,引用const字符串的语义应该是什么
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- Xcode 语义问题引用或以前定义的代码
- 使用移动和复制语义时函数匹配如何工作?
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 使用 std::分配器在 constexpr 中进行默认初始化
- 使用不兼容的分配器复制分配无序列图
- C++:矢量分配器行为、内存分配和智能指针
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 移动语义和深层/浅层复制之间有什么关系?
- 复制有状态分配器:标准库分配器语义和内部内存
- 如果分配器提供realloc语义,std::vector是否可以避免复制