将 std::allocate_shared 与多态资源分配器一起使用

Rob*_*p87 2 c++ shared-ptr allocator c++pmr

我正在尝试使用 a 创建共享指针std::pmr::monotonic_buffer_resource,但无法编译它。我缺少什么?

https://godbolt.org/z/R9​​jdju

#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);
}
Run Code Online (Sandbox Code Playgroud)
在 /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:使用 __alloc_rebind = typename std::__allocator_traits_base::__rebind 替换 'template<class _Alloc, class _Up> <_Alloc, _Up>::type [with _Alloc = std::pmr::monotonic_buffer_resource; _Up = std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>]':
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:542:13:需要从 'class std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:679:43:需要来自 'std::__shared_count<_Lp>::__shared_count(_Tp*&, std ::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::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&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = 双;__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&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = 双]'
/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&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>: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”中没有名为“type”的类型< std::pmr::monotonic_buffer_resource、std::_Sp_counted_ptr_inplace<double、std::pmr::monotonic_buffer_resource、__gnu_cxx::_S_atomic>、void>'
   78 | 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&& ...) [with _Tp = double; _Alloc = std::pmr::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&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = 双;__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&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = 双]'
/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&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>:7:66:需要从这里
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:682:16:错误:使用已删除的函数 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'
  682 | 682 自动 __pi = ::新 (__mem)
      | ^~~~~~~~~~~~~
  683 | 683 _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
在 <source>:2 包含的文件中:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory_resource:604:5:注意:此处声明
  604 | 604 monotonic_buffer_resource(const 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> 的参数 1: :_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {}; _Tp = 双;_Alloc = std::pmr::monotonic_buffer_resource; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
  546 | 546 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
      | ~~~~~~~^~~

Rem*_*eau 5

那个长错误消息基本上可以归结为这两个错误:

错误:'struct std::__allocator_traits_base::__rebind<std::pmr::monotonic_buffer_resource, std::_Sp_counted_ptr_inplace<double, std::pmr::monotonic_buffer_resource, __gnu_cxx::_S_atomic>, void> 中没有名为“type”的类型'

错误:使用已删除的函数 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'

std::pmr::monotonic_buffer_resource不满足std::allocate_shared()预期的要求,具体来说:

所有内存分配都是使用 的副本完成的,alloc必须满足分配器的要求。

特别是“a COPY of alloc”,它会失败,因为monotonic_buffer_resource的复制构造函数已被delete“复制”,因此无法复制。

正如 @MilesBudnek 在评论中所述,您可以将 a 包装monotonic_buffer_resource在 a 内std::pmr::polymorphic_allocator,它被设计用作Allocator标准容器的 an :

类模板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);
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/GLE4-5