gpt4 book ai didi

c++ - STL 的 allocator_traits 中静态成员函数的用途是什么?

转载 作者:太空狗 更新时间:2023-10-29 19:48:10 30 4
gpt4 key购买 nike

我正在尝试实现一个 STL 风格的容器类,我有一个关于在我的类中使用分配器的问题:

STL 的 allocator_traits 中的静态成员函数有何用途?

直到现在,我认为我应该实例化 allocator_type(可能通过某种空基优化来改善内存占用)。因此,我最终会得到这样的结果:

struct EmptyBaseOpt : allocator_type
{
EmptyBaseOpt(const allocator_type & a, allocator_type::const_pointer p)
: allocator_type(a), prefix_ptr(p) { }

allocator_type::pointer prefix_ptr;
}

EmptyBaseOpt ebo;

然后,我可以按以下方式使用分配器:

allocator_type & alloc = ebo;
alloc.allocate(100, ebo.prefix_ptr);

另一方面,C++11 中的 allocator_traits 似乎暗示了以下用法:

std::allocator_traits<allocator_type>::allocate(100, ebo.prefix_ptr);

我想这个静态allocate 成员函数可能会通过其默认构造函数创建一个allocator_type 的临时临时实例。但这会导致以下问题:

  1. 如果 allocator_type 是有状态分配器会发生什么?如果我在 allocator_traits 中使用静态成员函数而不是从 allocator_type 的实例调用非静态方法,这样的分配器是否能够保持它们的状态?

  2. 如果我可以直接使用 allocator_traits 中的静态成员函数,我为什么要实例化 allocator_type 并为 EBO 之类的东西烦恼?

  3. 如前所述,我的理解是任何类似类的模板参数都应该在我的容器类中实例化,以便允许这些参数的有状态版本。这种理解是否正确,它如何适应 allocator_traits 中的静态成员函数?

最佳答案

On the other hand, the allocator_traits in C++11 seem to imply the following usage:

std::allocator_traits<allocator_type>::allocate(100, ebo.prefix_ptr);

不,您错过了该函数调用最重要的参数:分配器。

I guess this static allocate member function will probably create a temporary ad-hoc instance of allocator_type via its default constructor.

不,因为您将分配器参数传递给函数。

What will happen if allocator_type is a stateful allocator?

它工作正常,因为您将该有状态分配器作为参数传递给使用它的函数。

Why should I instantiate allocator_type at all and bother with stuff like EBO if I can directly use the static member functions in allocator_traits instead?

因为你不能用它们代替。

As stated before, my understanding is that any class-like template parameters should be instantiated inside my container class in order to allow for stateful versions of these parameters. Is this understanding correct, and how does it fit with the static member functions in allocator_traits?

是的,你的理解是正确的,如果你使用得当,它很适合allocator_traits

allocator_traits 的要点是为大多数 Allocator 接口(interface)提供合理的默认值。这有两个目的:

  • 首先,在 C++11 中定义分配器更简单(您只需要提供 value_typeallocatedeallocate,一个用于重新绑定(bind)分配器和 operator==operator!= 的模板构造函数,因此现在编写简单的自定义分配器要简单得多。

  • 其次,它允许 C++11 容器使用仅满足 C++03 分配器要求的现有分配器。 C++03 分配器未定义嵌套成员,例如 C++11 容器查找的 propagate_on_container_swap,或新的可变参数 construct(pointer, Args&&...)允许使用任何参数构造对象的成员,而不仅仅是复制构造的(这是允许 emplace 工作的)。因此,通过在 allocator_traits 中包装分配器的使用,大多数分配器接口(interface)都被赋予了合理的默认值,因此现有的 C++03 代码使用带有容器的自定义分配器,例如 std::vector 如果使用 C++11 重新编译,构建不会突然失败。 std::vector 实现仅通过 allocator_traits 类型使用新成员,因此自定义分配器未更新以提供所有新成员并不重要这是 C++11 分配器要求的一部分。

关于c++ - STL 的 allocator_traits 中静态成员函数的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32136595/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com