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

标签 c++ shared-ptr allocator c++pmr

我正在尝试使用 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);
}
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/ext/alloc_traits.h:34,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_uninitialized.h:67,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:66,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h: In substitution of 'template<class _Alloc, class _Up> using __alloc_rebind = typename std::__allocator_traits_base::__rebind<_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:   required from '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:   required from '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:   required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::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:   required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>:7:66:   required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/alloc_traits.h:78:11: error: no type named 'type' in '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>'
   78 |     using __alloc_rebind
      |           ^~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h: In instantiation of '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:   required from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::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:   required from 'std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}; _Tp = double]'
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from 'std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; _Args = {}]'
<source>:7:66:   required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:682:16: error: use of deleted function 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'
  682 |    auto __pi = ::new (__mem)
      |                ^~~~~~~~~~~~~
  683 |      _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from <source>:2:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory_resource:604:5: note: declared here
  604 |     monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr.h:52,
                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/memory:84,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/shared_ptr_base.h:546:33: note:   initializing argument 1 of 'std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {}; _Tp = double; _Alloc = std::pmr::monotonic_buffer_resource; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]'
  546 |  _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
      |                          ~~~~~~~^~~

最佳答案

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

error: no type named 'type' in '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>'

error: use of deleted function 'std::pmr::monotonic_buffer_resource::monotonic_buffer_resource(const std::pmr::monotonic_buffer_resource&)'

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

All memory allocation is done using a copy of alloc, which must satisfy the Allocator requirements.

特别是“allocCOPY”,由于monotonic_buffer_resource的复制构造函数被delete而失败> 这样就无法复制。

正如 @MilesBudnek 在评论中所述,您可以将 monotonic_buffer_resource 包装在 std::pmr::polymorphic_allocator 中。 ,其设计用作 Allocator对于标准容器:

The class template std::pmr::polymorphic_allocator is an Allocator which exhibits different allocation behavior depending upon the std::pmr::memory_resource from which it is constructed.

例如:

#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

关于c++ - 将 std::allocate_shared 与多态资源分配器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62801417/

相关文章:

c++ - C++构造函数中点<函数名>的含义

c++ - std::tr1::shared_ptr 是如何实现的?

C++ 为基元调用 allocator.construct

c++ - 使用分配器

c++ - std::shared_ptr 在按引用传递时如何跨类层次结构转换?

c++ - std::allocate_shared,允许从自定义分配器和单次分配中分配共享指针引用计数

c++ - 无法从其他类获取单例类的实例

c++ - 在现有 Qt 项目中从源代码构建第 3 方库

C++ 模板返回带有类型名值的元组

c++ - 在列表中正确使用 boost::shared_ptr