《STL源码分析》学习笔记 — 空间配置器 — 构造和析构基本工具
正如我们前面所学习过的,在标准空间配置器中, construct 和 destroy 方法已经被最新的C++标准移除。这也符合模块化的思想。空间的管理来就分为两组功能:内存的申请与释放;对象的构造和析构。在C++20中,标准 allocator 的功能已经被简化到(或者说规范到)仅负责内存的申请与释放。对象的构造和析构则是由 stl_construct.h 中的函数进行管理。
一、文档注释
先看看该文档的注释:
/* This file provides the C++17 functions std::destroy_at, std::destroy, and
* std::destroy_n, and the C++20 function std::construct_at.
* It also provides std::_Construct, std::_Destroy,and std::_Destroy_n functions
* which are defined in all standard modes and so can be used in C++98-14 code.
* The _Destroy functions will dispatch to destroy_at during constant
* evaluation, because calls to that function are intercepted by the compiler
* to allow use in constant expressions.
*/
这个文件提供了用于C++17的 destroy_at、destroy、destroy_n,用于C++20的 construct_at(不知道为什么和前面的不是一个版本推出的)。它同样提供了 _Construct、_Destroy、_Destroy_n 函数,它们在所有标准模式中被定义,因此可以被用于 C++98-14 的代码。在常量表达式中,_Destroy 函数将被转发到 destroy_at方法中,因为在编译器中将会截断在常量表达式中对该方法的调用。
二、construct_at 和 destroy_at
#if __cplusplus >= 201703L
template <typename _Tp>
_GLIBCXX20_CONSTEXPR inline void destroy_at(_Tp* __location)
{
if constexpr (__cplusplus > 201703L && is_array_v<_Tp>)
{
for (auto& __x : *__location)
std::destroy_at(std::__addressof(__x));
}
else
__location->~_Tp();
}
#if __cplusplus > 201703L
template<typename _Tp, typename... _Args>
constexpr auto construct_at(_Tp* __location, _Args&&... __args)
noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))-> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))