动态内存管理
未初始化存储
提供数个工具以创建并访问未初始化存储
允许标准算法存储结果于未初始化内存的迭代器
std::raw_storage_iterator
template< class OutputIt, class T > class raw_storage_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>; | (C++17 前) | |
template< class OutputIt, class T > | (C++17 起) (弃用) (C++20 中移除) |
输出迭代器 std::raw_storage_iterator
使得标准算法能存储结果于未初始化内存。凡在算法写 T
类型对象到解引用后的迭代器时,对象被复制构造到该迭代器所指向的未初始化存储中的位置。模板形参 OutputIt
是任何满足遗留输出迭代器 (LegacyOutputIterator) 要求的类型,并拥有定义为返回对象的 operator* , operator& 对该对象返回 T*
类型值。通常,以类型 T*
为 OutputIt
。
类型要求
- OutputIt 必须满足遗留输出迭代器 (LegacyOutputIterator) 的要求。 |
成员函数
(构造函数) | 创建新的 raw_storage_iterator (公开成员函数) |
operator= | 在缓冲区中的被指向位置构造对象 (公开成员函数) |
operator* | 解引用迭代器 (公开成员函数) |
operator++operator++(int) | 推进迭代器 (公开成员函数) |
base (C++17 起) | 提供到被包装迭代器的访问 (公开成员函数) |
成员类型
成员类型 | 定义 |
iterator_category | std::output_iterator_tag |
value_type | void |
difference_type | void |
pointer | void |
reference | void |
要求通过从 std::iterator<std::output_iterator_tag, void, void, void, void> 继承获得成员类型 | (C++17 前) |
创建新的 raw_storage_iterator
std::raw_storage_iterator<OutputIt,T>::raw_storage_iterator
explicit raw_storage_iterator( OutputIt it ); |
初始化迭代器为指向与 it
所指向的相同值。
参数
it | - | 要指向的位置 |
在缓冲区中的被指向位置构造对象
std::raw_storage_iterator<OutputIt,T>::operator=
raw_storage_iterator& operator=( const T& el ); | (1) | |
raw_storage_iterator& operator=( T&& el ); | (2) | (C++17 起) |
1) 从 el 构造位于迭代器所指向位置的值。
2) 从 std::move(el) 构造位于迭代器所指向位置的值。
参数
el | - | 复制或移动来源的值 |
返回值
*this
解引用迭代器
std::raw_storage_iterator<OutputIt,T>::operator*
raw_storage_iterator& operator*(); |
解引用迭代器。
参数
(无)
返回值
*this
推进迭代器
std::raw_storage_iterator<OutputIt,T>::operator++, operator++(int)
raw_storage_iterator& operator++(); | ||
raw_storage_iterator operator++(int); |
推进迭代器。
1) 前自增。返回更新后的迭代器。
2) 后自增。返回迭代器的旧值。
参数
(无)
返回值
1) *this
2) 迭代器的旧值。
提供到被包装迭代器的访问
std::raw_storage_iterator<OutputIt,T>::base
OutputIt base() const; | (C++17 起) |
提供到传入此 raw_storage_iterator 构造函数的迭代器的访问。
参数
(无)
返回值
与 *this 指向同一对象的迭代器。
调用示例
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <random>
#include <vector>
#include <cassert>
#include <memory>
struct Cell
{
int x;
int y;
Cell(): x(0), y(0)
{
}
Cell(int a, int b): x(a), y(b) {}
Cell &operator +=(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator +(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator *(const Cell &cell)
{
x *= cell.x;
y *= cell.y;
return *this;
}
Cell &operator ++()
{
x += 1;
y += 1;
return *this;
}
bool operator <(const Cell &cell) const
{
if (x == cell.x)
{
return y < cell.y;
}
else
{
return x < cell.x;
}
}
bool operator >(const Cell &cell) const
{
if (x == cell.x)
{
return y > cell.y;
}
else
{
return x > cell.x;
}
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
friend Cell operator+(const Cell &lcell, const Cell &rcell)
{
Cell cell = lcell;
cell.x += rcell.x;
cell.y += rcell.y;
return cell;
}
friend Cell operator-(const Cell &lcell, const Cell &rcell)
{
Cell cell = lcell;
cell.x -= rcell.x;
cell.y -= rcell.y;
return cell;
}
friend Cell operator*(const Cell &lcell, const Cell &rcell)
{
Cell cell = lcell;
cell.x *= rcell.x;
cell.y *= rcell.y;
return cell;
}
friend Cell operator/(const Cell &lcell, const Cell &rcell)
{
Cell cell = lcell;
cell.x /= rcell.x;
cell.y /= rcell.y;
return cell;
}
friend Cell operator%(const Cell &lcell, const Cell &rcell)
{
Cell cell = lcell;
cell.x %= rcell.x;
cell.y %= rcell.y;
return cell;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
std::cout << "std::raw_storage_iterator" << std::endl;
std::cout << std::boolalpha;
const std::string strings[] = {"This", "is", "a", "test", "."};
std::string* pStrings = std::allocator<std::string>().allocate(5);
std::copy(std::begin(strings), std::end(strings),
std::raw_storage_iterator<std::string*, std::string>(pStrings));
for (std::string* pString = pStrings; pString != pStrings + 5; ++pString)
{
std::cout << *pString << std::endl;
pString->~basic_string<char>();
}
std::allocator<std::string>().deallocate(pStrings, 5);
std::mt19937 g{std::random_device{}()};
srand((unsigned)time(NULL));
auto generate = []()
{
int n = std::rand() % 10 + 110;
Cell cell{n, n};
return cell;
};
//3) 构造拥有 count 个有值 value 的元素的容器。
const Cell cells[] = {generate(), generate(), generate(), generate(), generate()};
std::cout << "Cell cells: ";
std::copy(std::begin(cells), std::end(cells), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << "Cell pCells: ";
Cell* pCells = std::allocator<Cell>().allocate(5);
std::copy(std::begin(cells), std::end(cells),
std::raw_storage_iterator<Cell*, Cell>(pCells));
for (Cell* pCell = pCells; pCell != pCells + 5; ++pCell)
{
std::cout << *pCell << " ";
pCell->~Cell();
}
std::cout << std::endl;
//创建新的 raw_storage_iterator
std::raw_storage_iterator<Cell*, Cell> raw_storage_iterator1(pCells);
//在缓冲区中的被指向位置构造对象
std::raw_storage_iterator<Cell*, Cell> raw_storage_iterator2 = raw_storage_iterator1;
std::cout << "std::raw_storage_iterator<Cell*, Cell>: "
<< typeid(raw_storage_iterator2).name() << std::endl;
//解引用迭代器
std::cout << "*std::raw_storage_iterator<Cell*, Cell>: "
<< typeid(*raw_storage_iterator2).name() << std::endl;
std::cout << std::endl;
std::allocator<std::string>().deallocate(pStrings, 5);
std::cout << std::endl;
std::vector<Cell> vector1(8, generate());
std::generate(vector1.begin(), vector1.end(), generate);
std::cout << "vector1: ";
std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
return 0;
}
输出
std::raw_storage_iterator
This
is
a
test
.
Cell cells: {112,112} {118,118} {115,115} {110,110} {110,110}
Cell pCells: {112,112} {118,118} {115,115} {110,110} {110,110}
std::raw_storage_iterator<Cell*, Cell>: St20raw_storage_iteratorIP4CellS0_E
*std::raw_storage_iterator<Cell*, Cell>: St20raw_storage_iteratorIP4CellS0_E
vector1: {118,118} {110,110} {113,113} {117,117} {114,114} {118,118} {117,117} {112,112}