标准库分配器语义和内部存储

标准库分配器语义和内部存储

本文介绍了复制状态分配器:标准库分配器语义和内部存储器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写一个分配器集合,目的是要在非常高性能的环境中使用,所以一点点限制使用(由编译器调解,而不是运行时错误)是可取的。我已经阅读了状态分配器的C ++ 11语义,以及它们如何被合适的容器使用。

I am writing a collection of allocators, with the intention that they're to be used in very high performance environments, so a little bit of restricted usage (mediated by the compiler, not runtime errors) is desirable. I've been reading into the C++11 semantics of stateful allocators and how they're expected to be used by conforming containers.

我粘贴了一个简单的分配器下面只包含allocator对象内的一块内存。在C ++ 03中,这是非法的。

I've pasted a simple allocator below which just contains a block of memory within the allocator object. In C++03, this was illegal.

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中,这是可行的吗? 复制有状态分配器意味着什么?由于目标容器调用源容器中所有元素的复制构造函数,必须显式复制分配器内部的内存,或者是默认构造函数?

In C++11, is this doable? What does it mean to copy a stateful allocator? Since the destination container invokes the copy constructor for all elements in the source container, must the memory inside the allocator be explicitly copied, or is default-construction enough?

这会导致问题,以性能为最终目标, propagate_on_container _ { copy swap move }? select_on_container_copy_construction 会返回什么?

This leads to the question, given performance as the ultimate goal, what are sane values for propagate_on_container_{copy,swap,move}? What does select_on_container_copy_construction return?

我很高兴根据要求提供更多详情,因为这似乎是一个相当模糊的问题 - 至少对me =)

I'm happy to provide more details on request because this seems a rather nebulous issue -- at least to me =)

这个争论来自于当 a == b 返回 $ true 对于同一 Allocator 类型的两个实例,保证分配 / code>可以用 b 解除分配。这似乎永远不是真的这个分配器。该标准还声明,当一个分配器是复制构造的,如 A a(b) a == b 确保返回true。

This contention arises from the definition that when a == b returns true for two instances of the same Allocator type, it is guaranteed that memory allocated with a may be deallocated with b. That seems to never be true for this allocator. The standard also states that when an allocator is copy-constructed, as in A a(b), a == b is guaranteed to return true.

推荐答案

分配器要求说,分配器的副本必须能够释放每个人的内存,因此通常不可能将内存存储在allocator对象中。

The allocator requirements say that copies of an allocator must be able to free each others' memory, so it is not generally possible to store the memory inside the allocator object.

这必须有效:

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)

所以你需要在allocator对象之外存储实际的内存(或者只能以非常有限的方式使用它,以确保对象不会超出范围,而任何东西都指向它拥有的内存)。

So you need to store the actual memory outside the allocator object (or only use it in very restricted ways that ensure the object doesn't go out of scope while anything is referring to memory it owns).

您还将努力重新绑定 internal_allocator ,应该怎么办?

You're also going to struggle with rebinding your internal_allocator, what should the following do?

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);

这篇关于复制状态分配器:标准库分配器语义和内部存储器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 07:43