Allocator for C++11
滿足C++11中對Alloocator的需求,所能寫出的最簡單allocator
注意
- 這邊的allocatte和deallocate不會呼叫Constructor/Destructor,只是單純的記憶體分配,為了簡單,直接用malloc/free
- 可以對兩個Allocator做比較的動作,如果兩者相等的話,可以達成在A進行allocate,而在B進行deallocate的動作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <cstdlib>
template <typename T> class Minallocator { public: using value_type = T;
T* allocate(size_t num) { return allocate(num, nullptr); } T* allocate(size_t num, const void* hint) { return reinterpret_cast<T*>(std::malloc(sizeof(T) * num)); } void deallocate(T* ptr, size_t num) { std::free(ptr); } Minallocator() = default; ~Minallocator() = default; Minallocator(const Minallocator&) = default; Minallocator(Minallocator&&) = default; Minallocator& operator=(const Minallocator&) = default; Minallocator& operator=(Minallocator&&) = default; };
template <typename T1, typename T2> bool operator==(const Minallocator<T1>& lhs,const Minallocator<T2>& rhs) { return true; }
template <typename T1, typename T2> bool operator!=(const Minallocator<T1>& lhs, const Minallocator<T2>& rhs) { return false; }
|
而要用自己的Allocate就可以這麼做
1
| std::vector<int, Minallocator<int>> v;
|
std::scoped_allocator_adaptor
不常用,有用到再說
rebind
已知T
類型的Allocator,想要根據相同策略拿到U
類型的Allocator
也就是說希望用同樣的方式來分配U
可以透過
1
| allocator<U>=allocator<T>::rebind<U>::other.
|
拿到,因此
std::allcoator<T>::rebind<U>::other
等同於std::allcoator<U>
Myallcoator<T>::rebind<U>::other
等同於Myallcoator<U>
在libstdc++中的實現
1 2 3 4 5
| template <typename _Tp1> struct rebind { typedef allocator<_Tp1> other; };
|
Problem with allocators and containers
這樣的程式碼會有問題
1 2 3 4
| ector<int, Minallocator<int>> pool_vec { 1, 2, 3, 4 }; vector<int, Other_allocator<int>> other_vec { };
other_vec = pool_vec;
|
因為兩者的Allocator Type不同,所以直接複製不行,所以只要兩者相同就行了,也就是C++17 PMR的初衷
C++17 Polymorphic Memory Resource
新提出來的memory_resource
是個asbtract class,不同的instance會有不同的行為
因此可以可以這樣做
1 2 3 4 5 6 7 8 9 10 11 12 13
| class my_memory_resource : public std::pmr::memory_resource { ... }; my_memory_resource mem_res; auto my_vector = std::pmr::vector<int>(0, &mem_res);
class other_memory_resource : public std::pmr::memory_resource { ... }; other_memory_resource mem_res_other; auto my_other_vector = std::pmr::vector<int>(0, &mes_res_other);
auto vec = my_vector; vec = my_other_vector;
|
Reference