STL allocator_traits中的静态成员函数的目的是什么?
What is the purpose of the static member functions in STL's allocator_traits?
我试图实现一个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
的临时临时实例。但这导致了以下问题:
如果
allocator_type
是一个有状态的分配器会发生什么?如果我使用allocator_traits
中的静态成员函数,而不是从allocator_type
的实例调用非静态方法,这些分配器是否能够保持它们的状态?为什么我应该实例化
allocator_type
,如果我可以直接使用allocator_traits
中的静态成员函数,那么就麻烦像EBO这样的东西?如前所述,我的理解是,任何类模板参数都应该在容器类中实例化,以便允许这些参数的有状态版本。这种理解是否正确?它如何与
allocator_traits
中的静态成员函数相适应?
另一方面,c++ 11中的allocator_traits似乎暗示了以下用法:
std::allocator_traits<allocator_type>::allocate(100, ebo.prefix_ptr);
不,你错过了函数调用最重要的参数:分配器。
我猜这个静态分配成员函数可能会通过它的默认构造函数创建一个临时的allocator_type实例。
不能,因为你给函数传递了一个分配器参数。
如果allocator_type是一个有状态的分配器会发生什么?
它工作得很好,因为您将有状态分配器作为参数传递给使用它的函数。
如果我可以直接使用allocator_traits中的静态成员函数,为什么我应该实例化allocator_type,并为像EBO这样的东西而烦恼?
因为你不能用它们代替。
如前所述,我的理解是任何类模板参数都应该在容器类中实例化,以便允许这些参数的有状态版本。这种理解是正确的吗?它如何与allocator_traits中的静态成员函数相适应?
是的,你的理解是正确的,如果你使用得当,它很适合allocator_traits
。
allocator_traits
的目的是为大多数Allocator接口提供合理的默认值。这有两个目的:
-
首先,在c++ 11中定义分配器更简单(您只需要提供
value_type
,allocate
,deallocate
,用于重新绑定分配器和operator==
和operator!=
的模板构造函数),因此编写简单的自定义分配器现在更简单。 -
其次,它允许仅满足c++ 03分配器要求的现有分配器被c++ 11容器使用。c++ 03分配器没有定义嵌套成员,比如c++ 11容器寻找的
propagate_on_container_swap
,或者新的可变construct(pointer, Args&&...)
成员,它允许用任何参数构造对象,而不仅仅是复制构造(这是允许emplace
工作的)。因此,通过在allocator_traits
中包装分配器的使用,大多数Allocator接口都被赋予了合理的默认值,这样,使用自定义分配器和容器(如std::vector
)的现有c++ 03代码在使用c++ 11重新编译时不会突然构建失败。std::vector
实现只通过allocator_traits
类型使用新成员,因此自定义分配器没有更新以提供c++ 11 allocator要求的所有新成员并不重要。
您似乎错过了allocator_traits
中的所有静态成员函数都将Alloc &
作为第一个参数的事实。也就是说,它们使用一个分配器类型的对象来完成它们的工作。
"仅通过allocator_traits
访问分配器"策略的原因是,如果分配器类型本身没有提供分配器操作,allocator_traits
的一些成员提供了分配器操作的默认实现。这适用于所有在c++ 11中添加到分配器要求中,而在c++ 03中不存在的成员。一个例子是construct
,如果分配器类型没有提供合适的construct
函数,它将调用放置new
运算符::new
。因此,这些默认值允许为c++ 03编写的分配器在c++ 11容器中保持不变。
此外,使用allocator_traits
允许更多的可定制性。可以为特定的分配器类指定allocator_traits
,并且可以通过对Alloc &
参数的不同调用来实现trait函数。
所以你对实例化allocator_type
的假设是正确的。不同之处在于,您不应该直接调用其成员函数(因为它们可能不存在),而是通过allocator_traits
中的静态访问器。
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 这里的字符串函数是什么意思
- 这个函数是什么意思(我的英语sry)
- C++ 中的 use 函数是什么?
- C++中的编译时函数是什么?
- 使用 DnsQuery 或 getaddrinfo 的正确函数是什么?
- Lua 中看起来像表的函数是什么?
- "AfxIsValidAddress"函数的等效标准函数是什么?
- 子类的构造函数后跟冒号后的基类构造函数是什么意思?
- MFC 用于计算控件的高光、阴影等的算法或函数是什么?
- 具有多个非可选参数的转换构造函数是什么样子的?为什么它有意义
- 不确定 c++ 中的常量函数是什么
- 指针的最快散列函数是什么
- 注册用于提升io_service的每个对象的回调函数是什么?
- 在 g++ 中生成 "-L" 和 -rpath 标志的等效函数是什么
- Boost.Python中的dispatch函数和forwarding函数是什么意思
- 给定情况下的良好哈希函数是什么
- C++ 中的"导出函数"是什么意思?
- C++ std::unordered_map 中使用的默认哈希函数是什么