将 std::allocate_shared 与多态资源分配器一起使用
Using std::allocate_shared with polymorphic resource allocators
我正在尝试创建带有std::pmr::monotonic_buffer_resource
的共享指针,但我无法对其进行编译。我错过了什么?
https://godbolt.org/z/R9jdju
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
std::shared_ptr<double> sp = std::allocate_shared<double>(mbr);
}
在/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ext/alloc_traits.h:34 包含的文件中, 来自/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_uninitialized.h:67, 来自/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:66, 来自<来源>:1:/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h:替换 'template:7:66:从这里需要/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h:78:11:错误:在"struct std::__allocator_traits_base::__rebind<std::p>, void>' 中没有名为"type"的类型 78 | 使用__alloc_rebind | ^~~~~~~~~~~~~~ 在/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52 包含的文件中, 来自/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84, 来自<来源>:1:/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:实例化'std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...)[_Tp = double; _Alloc = std::p mr::monotonic_buffer_resource; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]':/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71:从'std::__shared_ptr<_Tp,_Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>,_Args&& ...)中需要[_Alloc = std::p mr::monotonic_buffer_resource; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:408:59:从'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>,_Args&& ...)中要求[_Alloc = std::p mr::monotonic_buffer_resource; _Args = {}; _Tp = double]'/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:859:14:从'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...)中需要[_Tp = double; _Alloc = std::p mr::monotonic_buffer_resource; _Args = {}]'<来源>:7:66:从这里需要/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:682:16:错误:使用已删除的函数'std::p mr::monotonic_buffer_resource::monotonic_buffer_resource(const std::p mr::monotonic_buffer_resource&)' 682 | 自动__pi = ::新 (__mem) | ^~~~~~~~~~~~~ 683 | _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 在从<源>:2 包含的文件中:/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory_resource:604:5:注意:在此处声明 604 | monotonic_buffer_resource(常量 monotonic_buffer_resource&) = 删除; | ^~~~~~~~~~~~~~~~~~~~~~~~~ 在/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52 包含的文件中, 来自/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84, 来自<来源>:1:/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:546:33:注意:初始化参数 'std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...)[_Args = {}; _Tp = double; _Alloc = std::p mr::monotonic_buffer_resource; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]' 546 | _Sp_counted_ptr_inplace(_Alloc __a、_Args&... __args) | ~~~~~~~^~~来源>源>来源>来源>来源> 来源>
这条长错误消息基本上可以归结为以下 2 个错误:
错误:在"结构 std::__allocator_traits_base::__rebind<std::p>、void>"中没有名为"type"的类型
错误:使用已删除的函数"std::p mr::monotonic_buffer_resource::monotonic_buffer_resource(const std::p mr::monotonic_buffer_resource&)">
std::pmr::monotonic_buffer_resource
不满足std::allocate_shared()
期望的要求,特别是:
所有的内存分配都是使用
alloc
的副本完成的,它必须满足分配器的要求。
特别是"alloc
的副本">,它失败了,因为monotonic_buffer_resource
的复制构造函数是delete
的,所以它不能被复制。
如@MilesBudnek注释中所述,您可以将monotonic_buffer_resource
包装在std::pmr::polymorphic_allocator
中,该旨在用作标准容器的Allocator
:
类模板
std::pmr::polymorphic_allocator
是一个分配器,它根据构造它的std::pmr::memory_resource
表现出不同的分配行为。
例如:
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
auto sp = std::allocate_shared<double, std::pmr::polymorphic_allocator<double>>(&mbr);
}
https://godbolt.org/z/-xFfFY
或者:
#include <memory>
#include <memory_resource>
int main() {
char buffer[100];
std::pmr::monotonic_buffer_resource mbr(buffer, 100);
std::pmr::polymorphic_allocator<double> alloc(&mbr);
auto sp = std::allocate_shared<double>(alloc);
}
https://godbolt.org/z/GLE4-5
- 将 std::allocate_shared 与多态资源分配器一起使用
- 使用RAII在给定次数的迭代后重新分配资源
- 使用不兼容的分配器复制分配无序列图
- C++:矢量分配器行为、内存分配和智能指针
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 基于浅树的数据结构的内存分配器,用于频繁分配和解除分配
- 在不释放所有动态分配的资源的情况下结束程序是否有风险
- shared_ptr的删除程序是否存储在自定义分配器分配的内存中?
- 哪些资源是由智能指针管理的,而它们的内存不是由new分配的
- STD分配器是否会在堆上动态分配内存?它可以安全地删除内存吗?
- C++计划持续时间内(字体)资源的分配
- 分配分配器为多态对象分配内存
- 如何通过分配器分配内存[10] [10]
- 分配但不使用分配器的标准图书馆设施
- 如何安全地释放构造函数分配的资源
- 清理跨越Windows DLL模块边界的堆分配资源时出现问题
- 如何为分层分配的类使用分配器
- 如何实现分配器感知的容器分配
- 默认stl分配器如何分配
- ScopeGuard在一个函数中的多个资源分配和退出点的使用情况