572 lines
60 KiB
HTML
572 lines
60 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>C++ 具名要求:分配器 (Allocator)</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_named_req_Allocator skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading"><span style="font-size:0.7em; line-height:130%">C++ 具名要求:</span><span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span></h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-named_req.html">named req</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>封装访问/寻址,分配/解分配,以及对象的构造/析构的策略。</p>
|
|
<p>可能需要分配或释放内存的每个标准库组件,从 <code>std::string</code>、<code>std::vector</code> 和除 <code>std::array</code> 以外的所有容器,到 <code>std::shared_ptr</code> 和 <code>std::function</code>,都通过<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 进行这些操作:分配器是满足下列要求的类类型对象。</p>
|
|
<p>许多分配器要求的实现是可选的,因为所有知分配器类,包括标准库容器,都通过 <code>std::allocator_traits</code> 访问分配器,而 <span class="t-lc"><a href="cpp-memory-allocator_traits.html">std::allocator_traits</a></span> 提供这些要求的默认实现。</p>
|
|
<h3><span class="mw-headline" id=".E8.A6.81.E6.B1.82">要求</span></h3>
|
|
<p>给定</p>
|
|
<ul>
|
|
<li><code>T</code> ,无 cv 限定的对象类型</li>
|
|
<li><code>A</code> , <code>T</code> 类型的<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 类型</li>
|
|
<li><code>a</code> , <code>A</code> 类型对象</li>
|
|
<li><code>B</code> ,某无 cv 限定的对象类型 <code>U</code> 的对应<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 类型(由重绑定 <code>A</code> 获得)</li>
|
|
<li><code>b</code> , <code>B</code> 类型对象</li>
|
|
<li><code>p</code> , <code>allocator_traits<A>::pointer</code> 类型值,由调用 <span class="t-c"><span class="mw-geshi cpp source-cpp">allocator_traits<span class="sy1"><</span>A<span class="sy1">></span><span class="sy4">::</span><span class="me2">allocate</span><span class="br0">(</span><span class="br0">)</span></span></span> 获得</li>
|
|
<li><code>cp</code> , <code>allocator_traits<A>::const_pointer</code> 类型值,由从 <code>p</code> 转换获得</li>
|
|
<li><code>vp</code> , <code>allocator_traits<A>::void_pointer</code> 类型值,由从 <code>p</code> 转换获得</li>
|
|
<li><code>cvp</code> , <code>allocator_traits<A>::const_void_pointer</code> 类型值,由从 <code>cp</code> 或从 <code>vp</code> 转换获得</li>
|
|
<li><code>xp</code> ,指向某无 cv 限定类型 <code>X</code> 的可解引用的指针</li>
|
|
<li><code>r</code> ,由表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>p</span></span> 获得的 <code>T</code> 类型左值</li>
|
|
<li><code>n</code> , <code>allocator_traits<A>::size_type</code> 类型值</li>
|
|
</ul>
|
|
<table class="wikitable">
|
|
<caption>内部类型</caption>
|
|
<tr>
|
|
<th>类型标识</th>
|
|
<th>别名使用的类型</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">pointer</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i><sup id="cite_ref-1" class="reference"><a href="cpp-named_req-Allocator.html#cite_note-1">[1]</a></sup></td>
|
|
<td>
|
|
<ul>
|
|
<li>满足<a href="cpp-named_req-NullablePointer.html"><span style="font-style:italic">可空指针</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(NullablePointer)</span></a> 、<a href="cpp-named_req-RandomAccessIterator.html"><span style="font-style:italic">老式随机访问迭代器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(LegacyRandomAccessIterator)</span></a> 及<a href="cpp-named_req-ContiguousIterator.html"><span style="font-style:italic">老式连续迭代器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(LegacyContiguousIterator)</span></a> 。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_pointer</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i></td>
|
|
<td>
|
|
<ul>
|
|
<li>满足<a href="cpp-named_req-NullablePointer.html"><span style="font-style:italic">可空指针</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(NullablePointer)</span></a> 、<a href="cpp-named_req-RandomAccessIterator.html"><span style="font-style:italic">老式随机访问迭代器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(LegacyRandomAccessIterator)</span></a> 及<a href="cpp-named_req-ContiguousIterator.html"><span style="font-style:italic">老式连续迭代器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(LegacyContiguousIterator)</span></a> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">pointer</span></span></span> 可转换为 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_pointer</span></span></span> 。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">void_pointer</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i></td>
|
|
<td>
|
|
<ul>
|
|
<li>满足<a href="cpp-named_req-NullablePointer.html"><span style="font-style:italic">可空指针</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(NullablePointer)</span></a> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">pointer</span></span></span> 可转换为 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">void_pointer</span></span></span> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">B<span class="sy4">::</span><span class="me2">void_pointer</span></span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">void_pointer</span></span></span> 为同一类型。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_void_pointer</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i></td>
|
|
<td>
|
|
<ul>
|
|
<li>满足<a href="cpp-named_req-NullablePointer.html"><span style="font-style:italic">可空指针</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(NullablePointer)</span></a> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">pointer</span></span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_pointer</span></span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">void_pointer</span></span></span> 可转换为 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_void_pointer</span></span></span> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">B<span class="sy4">::</span><span class="me2">const_void_pointer</span></span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">const_void_pointer</span></span></span> 为同一类型。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">value_type</span></span></span></td>
|
|
<td><code>T</code></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">size_type</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i></td>
|
|
<td>
|
|
<ul>
|
|
<li>无符号整数类型。</li>
|
|
<li>能表示 <code>A</code> 所能分配的最大对象的大小。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">difference_type</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(未指明)</i></td>
|
|
<td>
|
|
<ul>
|
|
<li>有符号整数类型。</li>
|
|
<li>能表示任何二个指向 <code>A</code> 所分配的对象的指针的差</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="kw1">template</span> rebind<span class="sy1"><</span>U<span class="sy1">></span><span class="sy4">::</span><span class="me2">other</span></span></span><br />
|
|
<span class="t-mark">(可选)</span><sup id="cite_ref-2" class="reference"><a href="cpp-named_req-Allocator.html#cite_note-2">[2]</a></sup></td>
|
|
<td><code>B</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>对于任何 <code>U</code> , <span class="t-c"><span class="mw-geshi cpp source-cpp">B<span class="sy4">::</span><span class="kw1">template</span> rebind<span class="sy1"><</span>T<span class="sy1">></span><span class="sy4">::</span><span class="me2">other</span></span></span> 为 <code>A</code> 。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table class="wikitable">
|
|
<caption>指针上的操作</caption>
|
|
<tr>
|
|
<th>表达式</th>
|
|
<th>返回类型</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>p</span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">T<span class="sy3">&</span></span></span></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>cp</span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> T<span class="sy3">&</span></span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>cp</span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>p</span></span> 标识同一对象。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">p<span class="sy2">-</span><span class="sy1">></span>m</span></span></td>
|
|
<td><abbr title="T::m 的类型。"><i>(原状)</i></abbr></td>
|
|
<td>同 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>p<span class="br0">)</span>.<span class="me1">m</span></span></span> ,若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>p<span class="br0">)</span>.<span class="me1">m</span></span></span> 良定义。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">cp<span class="sy2">-</span><span class="sy1">></span>m</span></span></td>
|
|
<td><abbr title="T::m 的类型。"><i>(原状)</i></abbr></td>
|
|
<td>同 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>cp<span class="br0">)</span>.<span class="me1">m</span></span></span> ,若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>cp<span class="br0">)</span>.<span class="me1">m</span></span></span> 良定义</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">static_cast</span><span class="sy1"><</span>A<span class="sy4">::</span><span class="me2">pointer</span><span class="sy1">></span><span class="br0">(</span>vp<span class="br0">)</span></span></span></td>
|
|
<td><abbr title="A::pointer"><i>(原状)</i></abbr></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">static_cast</span><span class="sy1"><</span>A<span class="sy4">::</span><span class="me2">pointer</span><span class="sy1">></span><span class="br0">(</span>vp<span class="br0">)</span> <span class="sy1">==</span> p</span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">static_cast</span><span class="sy1"><</span>A<span class="sy4">::</span><span class="me2">const_pointer</span><span class="sy1">></span><span class="br0">(</span>cvp<span class="br0">)</span></span></span></td>
|
|
<td><abbr title="A::const_pointer"><i>(原状)</i></abbr></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">static_cast</span><span class="sy1"><</span>A<span class="sy4">::</span><span class="me2">const_pointer</span><span class="sy1">></span><span class="br0">(</span>cvp<span class="br0">)</span> <span class="sy1">==</span> cp</span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-pointer_traits.html"><span class="kw756">std::<span class="me2">pointer_traits</span></span></a><span class="sy1"><</span>A<span class="sy4">::</span><span class="me2">pointer</span><span class="sy1">></span><span class="sy4">::</span><span class="me2">pointer_to</span><span class="br0">(</span>r<span class="br0">)</span></span></span></td>
|
|
<td><abbr title="A::pointer"><i>(原状)</i></abbr></td>
|
|
<td></td>
|
|
</tr>
|
|
</table>
|
|
<table class="wikitable">
|
|
<caption>存储与生存期操作</caption>
|
|
<tr>
|
|
<th>表达式</th>
|
|
<th>返回类型</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">allocate</span><span class="br0">(</span>n<span class="br0">)</span></span></span></td>
|
|
<td rowspan="2"><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">pointer</span></span></span></td>
|
|
<td>分配适合一个 <span class="t-c"><span class="mw-geshi cpp source-cpp">T<span class="br0">[</span>n<span class="br0">]</span></span></span> 类型数组对象的存储并创建该数组,但不构造数组元素。可以抛异常。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">allocate</span><span class="br0">(</span>n, cvp<span class="br0">)</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td>同 <span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">allocate</span><span class="br0">(</span>n<span class="br0">)</span></span></span> ,但可能以未指定的方式使用 <code>cvp</code> ( <span class="t-c"><span class="mw-geshi cpp source-cpp">nullptr</span></span> 或从 <span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">allocate</span><span class="br0">(</span><span class="br0">)</span></span></span> 获得的指针)以辅助局部性。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">allocate_at_least</span><span class="br0">(</span>n<span class="br0">)</span></span></span> <span class="t-mark">(可选)</span> <span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">allocation_result</span><span class="sy1"><</span><br /></span></span>
|
|
<p> A<span class="sy4">::</span><span class="me2">pointer</span><span class="sy1">></span></p>
|
|
</td>
|
|
<td>分配适合一个 <span class="t-c"><span class="mw-geshi cpp source-cpp">T<span class="br0">[</span>cnt<span class="br0">]</span></span></span> 类型数组对象的存储并创建该数组,但不构造数组元素,然后返回 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">{</span>p, cnt<span class="br0">}</span></span></span> ,其中 <code>p</code> 指向存储而 <code>cnt</code> 不小于 <code>n</code> 。可以抛异常。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">deallocate</span><span class="br0">(</span>p, n<span class="br0">)</span></span></span></td>
|
|
<td><i>(不使用)</i></td>
|
|
<td>解分配 <code>p</code> 所指向的存储,该值必须由之前调用 <code>allocate</code> <span class="t-rev-inl t-since-cxx23"><span>或 <code>allocate_at_least</code></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span> 返回且未被中间对 <code>deallocate</code> 的调用非法化。 <code>n</code> 必须匹配先前传给 <code>allocate</code> 的值<span class="t-rev-inl t-since-cxx23"><span>或在经由 <code>allocate_at_last</code> 请求和返回的元素数之间(可以等于任一边界)</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>。不抛异常。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">max_size</span><span class="br0">(</span><span class="br0">)</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">size_type</span></span></span></td>
|
|
<td>能传递给 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">allocate</span><span class="br0">(</span><span class="br0">)</span></span></span> 的最大值。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">construct</span><span class="br0">(</span>xp, args<span class="br0">)</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(不使用)</i></td>
|
|
<td>于先前分配的 <code>xp</code> 所指向的存储构造 <code>X</code> 类型对象,以 <code>args</code> 为构造函数参数。</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">destroy</span><span class="br0">(</span>xp<span class="br0">)</span></span></span> <span class="t-mark">(可选)</span></td>
|
|
<td><i>(不使用)</i></td>
|
|
<td>销毁 <code>xp</code> 所指向的 <code>X</code> 类型对象,但不解分配存储。</td>
|
|
</tr>
|
|
</table>
|
|
<table class="wikitable">
|
|
<caption>实例间的关系</caption>
|
|
<tr>
|
|
<th>表达式</th>
|
|
<th>返回类型</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a1 <span class="sy1">==</span> a2</span></span></td>
|
|
<td rowspan="2"><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span></td>
|
|
<td>
|
|
<ul>
|
|
<li>仅若由分配器 <code>a1</code> 分配的存储能通过 <code>a2</code> 解分配才为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 。</li>
|
|
<li>建立自反、对称和传递关系。</li>
|
|
<li>不抛异常。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a1 <span class="sy3">!</span><span class="sy1">=</span> a2</span></span></td>
|
|
<td>
|
|
<ul>
|
|
<li>同 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">!</span><span class="br0">(</span>a1<span class="sy1">==</span>a2<span class="br0">)</span></span></span> 。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>声明</th>
|
|
<th>效果</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a1<span class="br0">(</span>a<span class="br0">)</span></span></span></td>
|
|
<td rowspan="2">复制构造 <code>a1</code> 使得 <span class="t-c"><span class="mw-geshi cpp source-cpp">a1 <span class="sy1">==</span> a</span></span> 。<br />
|
|
(注:每个<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 亦满足<a href="cpp-named_req-CopyConstructible.html"><span style="font-style:italic">可复制构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(CopyConstructible)</span></a> 。)</td>
|
|
<td rowspan="2">
|
|
<ul>
|
|
<li>不抛异常。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a1 <span class="sy1">=</span> a</span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a<span class="br0">(</span>b<span class="br0">)</span></span></span></td>
|
|
<td>构造 <code>a</code> 使得 <span class="t-c"><span class="mw-geshi cpp source-cpp">B<span class="br0">(</span>a<span class="br0">)</span><span class="sy1">==</span>b</span></span> 且 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="br0">(</span>b<span class="br0">)</span><span class="sy1">==</span>a</span></span> 。<br />
|
|
(这隐含所有由 <code>rebind</code> 联系的分配器均维护彼此的资源,例如内存池。)</td>
|
|
<td>
|
|
<ul>
|
|
<li>不抛异常。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a1<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>a<span class="br0">)</span><span class="br0">)</span></span></span></td>
|
|
<td rowspan="2">构造 <code>a1</code> 使得它等于先前 <code>a</code> 的值。</td>
|
|
<td rowspan="2">
|
|
<ul>
|
|
<li>不抛异常。</li>
|
|
<li>不更改 <code>a</code> 的值且 <span class="t-c"><span class="mw-geshi cpp source-cpp">a1 <span class="sy1">==</span> a</span></span> 。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a1 <span class="sy1">=</span> std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>a<span class="br0">)</span></span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A a<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>b<span class="br0">)</span><span class="br0">)</span></span></span></td>
|
|
<td>构造 <code>a</code> 使得它等于先前 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="br0">(</span>b<span class="br0">)</span></span></span> 的值。</td>
|
|
<td>
|
|
<ul>
|
|
<li>不抛异常。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>类型标识</th>
|
|
<th>别名使用的类型</th>
|
|
<th>要求</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">is_always_equal</span></span></span><br />
|
|
<span class="t-mark">(可选)</span> <span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
<td><span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::false_type</a></span> 或从它们派生。</td>
|
|
<td>
|
|
<ul>
|
|
<li>若二个 <code>A</code> 类型分配器始终比较相等则为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 。</li>
|
|
<li>(若不提供,则 <span class="t-lc"><a href="cpp-memory-allocator_traits.html">std::allocator_traits</a></span> 默认它为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-types-is_empty.html"><span class="kw508">std::<span class="me2">is_empty</span></span></a><span class="sy1"><</span>A<span class="sy1">></span><span class="sy4">::</span><span class="me2">type</span></span></span> 。)</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table class="wikitable">
|
|
<caption>容器操作上的影响</caption>
|
|
<tr>
|
|
<th>表达式</th>
|
|
<th>返回类型</th>
|
|
<th>描述</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">select_on_container_copy_construction</span><span class="br0">(</span><span class="br0">)</span></span></span><br />
|
|
<span class="t-mark">(可选)</span></td>
|
|
<td><code>A</code></td>
|
|
<td>
|
|
<ul>
|
|
<li>提供从当前使用 <code>a</code> 的容器复制构造容器所用的 <code>A</code> 的实例。</li>
|
|
<li>(通常返回 <code>a</code> 的副本或默认构造的 <code>A</code> 。)</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>类型标识</th>
|
|
<th>别名使用的类型</th>
|
|
<th>描述</th>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">propagate_on_container_copy_assignment</span></span></span><br />
|
|
<span class="t-mark">(可选)</span></td>
|
|
<td rowspan="3"><span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::false_type</a></span> 或从它们派生。</td>
|
|
<td>
|
|
<ul>
|
|
<li>若复制赋值使用 <code>A</code> 类型分配器的容器时需要复制它则为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或其派生类。</li>
|
|
<li>若此成员为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或从它派生,则 <code>A</code> 必须满足<a href="cpp-named_req-CopyAssignable.html"><span style="font-style:italic">可复制赋值</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(CopyAssignable)</span></a> 且复制操作必须不抛异常。</li>
|
|
<li>注意若源与目标容器的分配器不比较相等,则复制赋值必须用旧分配器解分配目标的内存,然后在复制元素(和分配器)前用新分配器分配内存。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">propagate_on_container_move_assignment</span></span></span><br />
|
|
<span class="t-mark">(可选)</span></td>
|
|
<td>
|
|
<ul>
|
|
<li>若移动赋值使用 <code>A</code> 类型分配器的容器时需要移动它则为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或其派生类。</li>
|
|
<li>若此成员为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或从它派生,则 <code>A</code> 必须满足<a href="cpp-named_req-MoveAssignable.html"><span style="font-style:italic">可移动赋值</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(MoveAssignable)</span></a> 且移动操作必须不抛异常。</li>
|
|
<li>若不提供此成员或它从 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::false_type</a></span> 派生,而源与目标容器的分配器不比较相等,则移动赋值不能取得源内存的所有权,并且必须单独地复制赋值或复制构造元素,按需重置其自身内存的大小。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy4">::</span><span class="me2">propagate_on_container_swap</span></span></span><br />
|
|
<span class="t-mark">(可选)</span></td>
|
|
<td>
|
|
<ul>
|
|
<li>若交换二个使用 <code>A</code> 类型分配器的容器时需要移动它们则为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或其派生类。</li>
|
|
<li>若此成员为 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::true_type</a></span> 或从它派生,则 <code>A</code> 的左值必须为<a href="cpp-named_req-Swappable.html"><span style="font-style:italic">可交换</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Swappable)</span></a> 且交换操作必须不抛异常。</li>
|
|
<li>若不提供此成员或它从 <span class="t-lc"><a href="cpp-types-integral_constant.html">std::false_type</a></span> 派生,且二个容器的分配器不比较相等,则容器交换的行为未定义。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<p>注:</p>
|
|
<ol class="references">
|
|
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="cpp-named_req-Allocator.html#cite_ref-1">↑</a></span> <span class="reference-text">参阅后述<a href="cpp-named_req-Allocator.html#.E7.BC.80.E9.A5.B0.E6.8C.87.E9.92.88">缀饰指针</a>。</span></li>
|
|
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="cpp-named_req-Allocator.html#cite_ref-2">↑</a></span> <span class="reference-text"><code>rebind</code> 仅若分配器是形式为 <span class="t-c"><span class="mw-geshi cpp source-cpp">SomeAllocator<span class="sy1"><</span>T, Args<span class="sy1">></span></span></span> 的模板,其中 <code>Args</code> 是零或更多个额外的类型模板形参才为可选(由 <span class="t-lc"><a href="cpp-memory-allocator_traits.html">std::allocator_traits</a></span> 提供)。</span></li>
|
|
</ol>
|
|
<p>给定</p>
|
|
<ul>
|
|
<li><code>x1</code> 与 <code>x2</code> ,(可能不同)类型 <code>X::void_pointer</code> 、 <code>X::const_void_pointer</code> 、 <code>X::pointer</code> 或 <code>X::const_pointer</code> 的对象。</li>
|
|
</ul>
|
|
<p>则 <code>x1</code> 与 <code>x2</code> 为<i>等价值</i>的指针值,当且仅当 <code>x1</code> 与 <code>x2</code> 能用 <code>static_cast</code> ,仅使用这四个类型的序列显式转换成二个对应的 <code>X::const_pointer</code> 类型对象 <code>px1</code> 与 <code>px2</code> ,而表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">px1 <span class="sy1">==</span> px2</span></span> 求值为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 。</p>
|
|
<p>给定</p>
|
|
<ul>
|
|
<li><code>w1</code> 与 <code>w2</code> , <code>X::void_pointer</code> 类型对象。</li>
|
|
</ul>
|
|
<p>则对于表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">w1 <span class="sy1">==</span> w2</span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp">w1 <span class="sy3">!</span><span class="sy1">=</span> w2</span></span> ,可将一个或两个对象替换成<i>等价值</i>的 <code>X::const_void_pointer</code> 类型对象而无语义更改。</p>
|
|
<p>给定</p>
|
|
<ul>
|
|
<li><code>p1</code> 与 <code>p2</code> , <code>X::pointer</code> 类型对象</li>
|
|
</ul>
|
|
<p>则对于表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy1">==</span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy3">!</span><span class="sy1">=</span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy1"><</span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy1"><=</span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy1">>=</span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy1">></span> p2</span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp">p1 <span class="sy2">-</span> p2</span></span> ,可将一个或两个对象替换成<i>等价值</i>的 <code>X::const_pointer</code> 类型对象而无语义更改。</p>
|
|
<p>以上要求使得能比较<a href="cpp-named_req-Container.html"><span style="font-style:italic">容器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Container)</span></a> 的 <code>iterator</code> 与 <code>const_iterator</code> 。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<h4><span class="mw-headline" id=".E5.88.86.E9.85.8D.E5.99.A8.E5.AE.8C.E6.95.B4.E6.80.A7.E8.A6.81.E6.B1.82">分配器完整性要求</span></h4>
|
|
<p>若无论 <code>T</code> 是否为完整类型下列二者皆为真,则针对类型 <code>T</code> 的分配器类型 <code>X</code> 还额外满足<i>分配器完整性要求</i>:</p>
|
|
<ul>
|
|
<li><code>X</code> 是完整类型</li>
|
|
<li>除 <code>value_type</code> 之外,所有 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-allocator_traits.html"><span class="kw701">std::<span class="me2">allocator_traits</span></span></a><span class="sy1"><</span>X<span class="sy1">></span></span></span> 的成员都是完整类型。</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.9C.89.E7.8A.B6.E6.80.81.E4.B8.8E.E6.97.A0.E7.8A.B6.E6.80.81.E5.88.86.E9.85.8D.E5.99.A8">有状态与无状态分配器</span></h3>
|
|
<p>每个<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 类型要么是<i>有状态</i>要么是<i>无状态</i>。通常来说,有状态分配器类型能拥有代表有别的内存资源的不相等值,而无状态分配器类型代表单一内存资源。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx11">
|
|
<td>
|
|
<p>尽管不要求自定义分配器为无状态,标准库中是否及如何支持分配器是实现定义的。若实现不支持使用不相等的分配器值,则这种使用可能导致实现定义的运行时错误或未定义行为。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>定制分配器可含有状态。每个容器或另一知分配器对象存储提供的分配器的实例并通过 <span class="t-lc"><a href="cpp-memory-allocator_traits.html">std::allocator_traits</a></span> 控制分配器替换。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>无状态分配器类型的实例始终比较相等。无状态分配器类型常实现为空类并适合<a href="cpp-language-ebo.html">空基类优化</a>。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p><span class="t-lc"><a href="cpp-memory-allocator_traits.html">std::allocator_traits</a></span> 的成员类型 <code>is_always_equal</code> 有意用于确定分配器类型是否为无状态。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E7.BC.80.E9.A5.B0.E6.8C.87.E9.92.88">缀饰指针</span></h3>
|
|
<p>当成员类型 <code>pointer</code> 不是原生指针时,它通常被称为“<a rel="nofollow" class="external text" href="https://wg21.link/p0773r0">缀饰指针(fancy pointer)</a>”。这种指针曾为支持分段内存架构而引入,并在当今用于访问在某些不同于原生指针所访问的同质虚拟地址空间的地址空间中所分配的对象。缀饰指针的一个实例是映射的不依赖地址指针 <a rel="nofollow" class="external text" href="http://www.boost.org/doc/libs/release/doc/html/interprocess/offset_ptr.html"><code>boost::interprocess::offset_ptr</code></a>,它使得在共享内存和在每个进程中映射到不同地址的映射到内存文件中,分配 <span class="t-lc"><a href="cpp-container-set.html">std::set</a></span> 一类的基于结点的数据结构可行。<span class="t-rev-inl t-since-cxx11"><span>通过类模板 <span class="t-lc"><a href="cpp-memory-pointer_traits.html">std::pointer_traits</a></span> ,</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>可以独立于提供缀饰指针的分配器而使用它们。<span class="t-rev-inl t-since-cxx20"><span>能用函数 <span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">to_address</span></span></span> 从缀饰指针获得裸指针。</span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span></p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx11">
|
|
<td>
|
|
<p>在标准库中使用缀饰指针和定制的大小/差类型是条件性支持的。实现可以要求成员类型 <code>pointer</code> 、 <code>const_pointer</code> 、 <code>size_type</code> 和 <code>difference_type</code> 分别为 <span class="t-c"><span class="mw-geshi cpp source-cpp">value_type<span class="sy2">*</span></span></span> 、 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> value_type<span class="sy2">*</span></span></span> 、 <span class="t-lc"><a href="cpp-types-size_t.html">std::size_t</a></span> 和 <span class="t-lc"><a href="cpp-types-ptrdiff_t.html">std::ptrdiff_t</a></span> 。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.A0.87.E5.87.86.E5.BA.93">标准库</span></h3>
|
|
<p>下列标准库组件满足<span style="font-style:italic">分配器</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Allocator)</span> 要求:</p>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-allocator.html"><span class="t-lines"><span>allocator</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>默认的分配器<br />
|
|
<span class="t-mark">(类模板)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-scoped_allocator_adaptor.html"><span class="t-lines"><span>scoped_allocator_adaptor</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>为多级容器实现的多级分配器<br />
|
|
<span class="t-mark">(类模板)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-polymorphic_allocator.html"><span class="t-lines"><span>polymorphic_allocator</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx17">(C++17)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>以 <span class="t-lc">std::memory_resource</span> 构造,支持基于它的运行时多态的分配器<br />
|
|
<span class="t-mark">(类模板)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<p>一个 C++11 分配器,但添加了 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">[</span><span class="br0">[</span>nodiscard<span class="br0">]</span><span class="br0">]</span></span></span> 以符合 C++20 风格。</p>
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <cstdlib></span>
|
|
<span class="co2">#include <new></span>
|
|
<span class="co2">#include <limits></span>
|
|
<span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <vector></span>
|
|
|
|
<span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">class</span> T<span class="sy1">></span>
|
|
<span class="kw1">struct</span> Mallocator
|
|
<span class="br0">{</span>
|
|
<span class="kw1">typedef</span> T value_type<span class="sy4">;</span>
|
|
|
|
Mallocator <span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
|
|
<span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">class</span> U<span class="sy1">></span> <span class="kw4">constexpr</span> Mallocator <span class="br0">(</span><span class="kw4">const</span> Mallocator <span class="sy1"><</span>U<span class="sy1">></span><span class="sy3">&</span><span class="br0">)</span> <span class="kw1">noexcept</span> <span class="br0">{</span><span class="br0">}</span>
|
|
|
|
<span class="br0">[</span><span class="br0">[</span>nodiscard<span class="br0">]</span><span class="br0">]</span> T<span class="sy2">*</span> allocate<span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>n <span class="sy1">></span> <a href="cpp-types-numeric_limits.html"><span class="kw344">std::<span class="me2">numeric_limits</span></span></a><span class="sy1"><</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a><span class="sy1">></span><span class="sy4">::</span><span class="me2">max</span><span class="br0">(</span><span class="br0">)</span> <span class="sy2">/</span> sizeof<span class="br0">(</span>T<span class="br0">)</span><span class="br0">)</span>
|
|
<span class="kw1">throw</span> <a href="cpp-memory-new-bad_array_new_length.html"><span class="kw694">std::<span class="me2">bad_array_new_length</span></span></a><span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">auto</span> p <span class="sy1">=</span> <span class="kw1">static_cast</span><span class="sy1"><</span>T<span class="sy2">*</span><span class="sy1">></span><span class="br0">(</span><a href="cpp-memory-c-malloc.html"><span class="kw759">std::<span class="me2">malloc</span></span></a><span class="br0">(</span>n<span class="sy2">*</span>sizeof<span class="br0">(</span>T<span class="br0">)</span><span class="br0">)</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
report<span class="br0">(</span>p, n<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">return</span> p<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw1">throw</span> <a href="cpp-memory-new-bad_alloc.html"><span class="kw693">std::<span class="me2">bad_alloc</span></span></a><span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">void</span> deallocate<span class="br0">(</span>T<span class="sy2">*</span> p, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n<span class="br0">)</span> <span class="kw1">noexcept</span> <span class="br0">{</span>
|
|
report<span class="br0">(</span>p, n, <span class="nu0">0</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-memory-c-free.html"><span class="kw763">std::<span class="me2">free</span></span></a><span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw1">private</span><span class="sy4">:</span>
|
|
<span class="kw4">void</span> report<span class="br0">(</span>T<span class="sy2">*</span> p, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> n, <span class="kw4">bool</span> alloc <span class="sy1">=</span> <span class="kw2">true</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="br0">(</span>alloc <span class="sy4">?</span> <span class="st0">"Alloc: "</span> <span class="sy4">:</span> <span class="st0">"Dealloc: "</span><span class="br0">)</span> <span class="sy1"><<</span> sizeof<span class="br0">(</span>T<span class="br0">)</span><span class="sy2">*</span>n
|
|
<span class="sy1"><<</span> <span class="st0">" bytes at "</span> <span class="sy1"><<</span> <a href="cpp-io-manip-hex.html"><span class="kw1782">std::<span class="me2">hex</span></span></a> <span class="sy1"><<</span> <a href="cpp-io-manip-showbase.html"><span class="kw1766">std::<span class="me2">showbase</span></span></a>
|
|
<span class="sy1"><<</span> <span class="kw1">reinterpret_cast</span><span class="sy1"><</span><span class="kw4">void</span><span class="sy2">*</span><span class="sy1">></span><span class="br0">(</span>p<span class="br0">)</span> <span class="sy1"><<</span> <a href="cpp-io-manip-hex.html"><span class="kw1781">std::<span class="me2">dec</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">class</span> T, <span class="kw1">class</span> U<span class="sy1">></span>
|
|
<span class="kw4">bool</span> operator<span class="sy1">==</span><span class="br0">(</span><span class="kw4">const</span> Mallocator <span class="sy1"><</span>T<span class="sy1">></span><span class="sy3">&</span>, <span class="kw4">const</span> Mallocator <span class="sy1"><</span>U<span class="sy1">></span><span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">class</span> T, <span class="kw1">class</span> U<span class="sy1">></span>
|
|
<span class="kw4">bool</span> operator<span class="sy3">!</span><span class="sy1">=</span><span class="br0">(</span><span class="kw4">const</span> Mallocator <span class="sy1"><</span>T<span class="sy1">></span><span class="sy3">&</span>, <span class="kw4">const</span> Mallocator <span class="sy1"><</span>U<span class="sy1">></span><span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">false</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-container-vector.html"><span class="kw1269">std::<span class="me2">vector</span></span></a><span class="sy1"><</span><span class="kw4">int</span>, Mallocator<span class="sy1"><</span><span class="kw4">int</span><span class="sy1">>></span> v<span class="br0">(</span><span class="nu0">8</span><span class="br0">)</span><span class="sy4">;</span>
|
|
v.<span class="me1">push_back</span><span class="br0">(</span><span class="nu0">42</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>可能的输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">Alloc: 32 bytes at 0x2020c20
|
|
Alloc: 64 bytes at 0x2023c60
|
|
Dealloc: 32 bytes at 0x2020c20
|
|
Dealloc: 64 bytes at 0x2023c60</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
|
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
|
<table class="dsctable" style="font-size:0.8em">
|
|
<tr>
|
|
<th>DR</th>
|
|
<th>应用于</th>
|
|
<th>出版时的行为</th>
|
|
<th>正确行为</th>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue179">LWG 179</a></td>
|
|
<td>C++98</td>
|
|
<td>未要求 <code>pointer</code> 与 <code>const_pointer</code> 可相互比较</td>
|
|
<td>已要求</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.link/P0593R6">P0593R6</a></td>
|
|
<td>C++98</td>
|
|
<td>未要求 <code>allocate</code> 在其所分配的存储中创建数组</td>
|
|
<td>已要求</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2016">LWG 2016</a></td>
|
|
<td>C++11</td>
|
|
<td>分配器的复制、移动与交换操作在使用时可能抛出</td>
|
|
<td>要求不抛出</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2263">LWG 2263</a></td>
|
|
<td>C++11</td>
|
|
<td>LWG179 的解决方案在 C++11 中意外丢失<br />
|
|
且未被推广到 <code>void_pointer</code> 与 <code>const_void_pointer</code></td>
|
|
<td>恢复并推广</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2593">LWG 2593</a></td>
|
|
<td>C++11</td>
|
|
<td>从分配器移动可能修改其值</td>
|
|
<td>禁止修改</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|