std::allocator_traits
template< class Alloc > | (C++11 起) |
allocator_traits
类模板提供访问分配器 (Allocator) 各种属性的标准化方式。标准容器和其他标准库组件通过此模板访问分配器,这使得能以任何类类型为分配器,只要用户提供的 allocator_traits
特化实现所有要求的功能。
std::allocator_traits<Alloc>::construct
template< class T, class... Args > | (C++11 起) |
若可能,则在 p
所指向的分配的未初始化存储构造 T
类型对象,通过调用
a.construct(p, std::forward<Args>(args)...)
若以上不可行(例如无 construct()
成员函数),则调用如下的布置 new
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)
a | - | 用于构造的分配器 |
args... | - | 传递给 a.construct() 或布置 new 的参数 |
(无)
此函数为标准库容器在插入、复制或移动元素时所用。
因为此函数提供到布置 new 的自动回落,故 C++11 起成员函数 construct()
是分配器 (Allocator) 的可选要求。
std::allocator_traits<Alloc>::destroy
template< class T > | (C++11 起) |
调用 p
所指向对象的析构函数。若可能,则通过调用 a.destroy(p) 这么做。若不可能(例如 a
无成员函数 destroy()
),则直接调用 *p
的析构函数,同 p->~T() 。
a | - | 用于析构的分配器 |
p | - | 指向要被销毁的对象的指针 |
(无)
因为此函数提供到析构函数的自动回落,故 C++11 起成员函数 destroy()
是分配器 (Allocator) 的可选要求。
#include <iostream>
#include <memory>
struct Cell
{
int x;
int y;
Cell()
{
std::cout << __FUNCTION__;
}
Cell(int a, int b): x(a), y(b)
{
std::cout << __FUNCTION__;
}
~Cell()
{
std::cout << __FUNCTION__;
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
bool operator <(const Cell &cell) const
{
if (x < cell.x)
{
return true;
}
return y < cell.y;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
//2) 附带地传递内存位置提示 hint 。若可能则调用 a.allocate(n, hint) 。
//若不可能(例如无双参数成员函数 allocate() ),则调用 a.allocate(n)
std::allocator<Cell> allocatorCell;
std::allocator_traits<std::allocator<Cell>> allocator_traitsCell;
Cell *pointerCell = allocator_traitsCell.allocate(allocatorCell, 10, nullptr);
for (int i = 0; i < 10; i++)
{
//可能,则在 p 所指向的分配的未初始化存储构造 T 类型对象,通过调用
//a.construct(p, std::forward<Args>(args)...)
allocator_traitsCell.construct(allocatorCell, (pointerCell + i), i * 100, i * 100);
std::cout << " allocator: " << (pointerCell + i) << " "
<< *(pointerCell + i) << std::endl;
}
std::cout << std::endl;
//调用 p 所指向对象的析构函数。若可能,则通过调用 a.destroy(p) 这么做。
//若不可能(例如 a 无成员函数 destroy() ),则直接调用 *p 的析构函数,同 p->~T() 。
for (int i = 0; i < 10; i++)
{
//可能,则在 p 所指向的分配的未初始化存储构造 T 类型对象,通过调用
//a.construct(p, std::forward<Args>(args)...)
allocator_traitsCell.destroy(allocatorCell, (pointerCell + i));
std::cout << " allocator: " << (pointerCell + i) << " "
<< *(pointerCell + i) << std::endl;
}
std::cout << std::endl;
return 0;
}
Cell allocator: 0x1037ad8 {0,0}
Cell allocator: 0x1037ae0 {100,100}
Cell allocator: 0x1037ae8 {200,200}
Cell allocator: 0x1037af0 {300,300}
Cell allocator: 0x1037af8 {400,400}
Cell allocator: 0x1037b00 {500,500}
Cell allocator: 0x1037b08 {600,600}
Cell allocator: 0x1037b10 {700,700}
Cell allocator: 0x1037b18 {800,800}
Cell allocator: 0x1037b20 {900,900}
~Cell allocator: 0x1037ad8 {0,0}
~Cell allocator: 0x1037ae0 {100,100}
~Cell allocator: 0x1037ae8 {200,200}
~Cell allocator: 0x1037af0 {300,300}
~Cell allocator: 0x1037af8 {400,400}
~Cell allocator: 0x1037b00 {500,500}
~Cell allocator: 0x1037b08 {600,600}
~Cell allocator: 0x1037b10 {700,700}
~Cell allocator: 0x1037b18 {800,800}
~Cell allocator: 0x1037b20 {900,900}