【问题标题】:Using std::allocate_shared with polymorphic resource allocators将 std::allocate_shared 与多态资源分配器一起使用
【发布时间】:2020-10-29 06:07:15
【问题描述】:

我正在尝试使用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:使用 __alloc_rebind = typename std::__allocator_traits_base::__rebind 替换 'template<_alloc _up>::type [with _Alloc = std::pmr::monotonic_buffer_resource; _Up = std::_Sp_counted_ptr_inplace]': /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' /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, _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 = {}]' :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 , void>' 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, _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 = {}]' :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章自动 __pi = ::new (__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(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章_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) | ~~~~~~~^~~

【问题讨论】:

  • 我不认为memory_resource 本身实现了分配器接口。您需要将mbr 包装在std::pmr::polymorphic_allocator 中。

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


【解决方案1】:

那长长的错误信息基本上归结为这两个错误:

错误:'struct std::__allocator_traits_base::__rebind<:pmr::monotonic_buffer_resource std::_sp_counted_ptr_inplace std::pmr::monotonic_buffer_resource __gnu_cxx::_s_atomic> 中没有名为“type”的类型, 无效>'

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

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

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

特别是“a COPY of alloc”,因为monotonic_buffer_resource 的复制构造函数是delete,所以它不能被复制。

正如@MilesBudnek 在 cmets 中所说,您可以将monotonic_buffer_resource 包装在std::pmr::polymorphic_allocator 中,该std::pmr::polymorphic_allocator 旨在用作标准容器的Allocator

类模板std::pmr::polymorphic_allocator 是一个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

【讨论】:

  • 嗨 Remy,感谢您的编辑和提问。那么说当前无法从 monotonic_buffer_resource 创建 shared_ptr 实例是否正确?或者可能有一些解决方法可以解决无法复制 MBR 的问题?或许是某种程度的间接?
  • @RoboCop87 查看我的最新编辑。您可以通过polymorphic_allocator间接使用monotonic_buffer_resource
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 2020-06-13
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
相关资源
最近更新 更多