将 std::allocate_shared 与多态资源分配器一起使用
Using std::allocate_shared with polymorphic resource allocators
我正在尝试使用 std::pmr::monotonic_buffer_resource
创建共享指针,但无法编译。我错过了什么?
#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
does not satisfy the requirements that std::allocate_shared()
期望,特别是:
All memory allocation is done using a copy of alloc
, which must satisfy the Allocator requirements.
特别是“alloc
的 COPY”,它失败了,因为 monotonic_buffer_resource
的复制构造函数是 delete
所以无法复制。
正如@MilesBudnek 在评论中所述,对于标准容器,您可以将 monotonic_buffer_resource
包装在 std::pmr::polymorphic_allocator
, which is designed to be used as an 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);
}
或者:
#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);
}
我正在尝试使用 std::pmr::monotonic_buffer_resource
创建共享指针,但无法编译。我错过了什么?
#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
does not satisfy the requirements that std::allocate_shared()
期望,特别是:
All memory allocation is done using a copy of
alloc
, which must satisfy the Allocator requirements.
特别是“alloc
的 COPY”,它失败了,因为 monotonic_buffer_resource
的复制构造函数是 delete
所以无法复制。
正如@MilesBudnek 在评论中所述,对于标准容器,您可以将 monotonic_buffer_resource
包装在 std::pmr::polymorphic_allocator
, which is designed to be used as an Allocator
中:
The class template
std::pmr::polymorphic_allocator
is an Allocator which exhibits different allocation behavior depending upon thestd::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);
}
或者:
#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);
}