從https://en.cppreference.com/w/cpp/memory/shared_ptr/allocate_shared:
template< class T, class Alloc, class... Args > shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... args );存盤通常大于
sizeof(T)為共享指標的控制塊和T物件使用一個分配。...所有記憶體分配都是使用 的副本完成的alloc,它必須滿足分配器的要求。
然后使用什么型別來分配上述存盤?換句話說,Alloc::value_type分配器的要求之一應該是什么?
uj5u.com熱心網友回復:
實際使用的型別取決于實作。根據分配器的要求和std::allocator_traits特征類模板的幫助,任何分配器都可以rebind通過std::allocator_traits<A>::rebind_alloc<T>機制被編輯到另一種型別。
假設你有一個分配器
template<class T>
class MyAlloc { ... };
如果你寫:
std::allocate_shared<T>(MyAlloc<T>{});
這并不意味著MyAlloc<T>將用于執行分配。如果在內部我們需要分配另一個型別的物件S,我們可以通過
std::allocator_traits<MyAlloc<T>>::rebind_alloc<S>
它被定義為如果MyAlloc它本身不提供rebind<U>::other成員型別別名,則使用默認實作,它回傳MyAlloc<S>. 分配器物件是由適當的轉換構造器傳遞給std::allocate_shared()(此處,MyAlloc<T>{})的物件構造的MyAlloc<S>(請參閱分配器要求)。
讓我們來看看一些特定的實作——libstdc 。對于上面的行,實際分配由
MyAlloc<std::_Sp_counted_ptr_inplace<T, Alloc<T>, (__gnu_cxx::_Lock_policy)2>
這是合理的:std::allocate_shared()為同時包含T控制塊和控制塊的物件分配記憶體。_Sp_counted_ptr_inplace<T, ...>就是這樣一個物件。它包含T在_M_storage資料成員中:
__gnu_cxx::__aligned_buffer<T> _M_storage;
許多其他地方也使用相同的機制。例如,std::list<T, Alloc>使用它來獲得一個分配器,然后用于分配串列節點,這些節點除了T保存指向其鄰居的指標外。
一個有趣的相關問題是為什么分配器不是模板模板引數,這似乎是一個自然的選擇。在這里討論。
uj5u.com熱心網友回復:
沒關系。型別必須只滿足分配器要求([util.smartptr.shared.create]/2,也在 C 11 中)。
其中一個要求是,對于每個(cv-unqualified)物件型別U,Alloc::rebind<U>::other為 a value_typeof產生相應的分配器型別U(或者如果這不是直接在分配器型別中allocator_-traits實作,則可以通過替換(第一個)模板引數來提供默認實作的Alloc專業化的類模板。)
這樣,無論value_type您傳遞的分配器是什么,std::allocate_shared都可以通過重新系結獲得組合存盤所需的(未指定)型別的分配器。
例如,與
struct MyType {};
int main() {
std::cout << "MyType size is " << sizeof(MyType) << "\n";
allocator<MyType> a;
auto x = std::allocate_shared<MyType>(a);
}
哪里allocator是最小分配器實作列印有關每個分配呼叫的詳細資訊typeid,我使用 libstdc 獲得當前 GCC:
MyType size is 1
Allocating for 1 objects of type St23_Sp_counted_ptr_inplaceI6MyType9allocatorIS0_ELN9__gnu_cxx12_Lock_policyE2EE
with size 24 each.
并使用當前的 Clang 和 libc :
MyType size is 1
Allocating for 1 objects of type NSt3__120__shared_ptr_emplaceI6MyType9allocatorIS1_EEE
with size 32 each.
https://godbolt.org/z/bPqeYTP7Y
uj5u.com熱心網友回復:
什么應該是 Alloc::value_type
分配器的要求與分配器要求中的Alloc::value_type相同T- 不要與Tof混淆allocate_shared。因此,例如,間接通過Alloc::?pointer必須產生一個型別的值Alloc::value_type&。
沒有要求它Alloc::value_type需要為std::allocate_shared,只要它符合分配器的要求。
std::allocate_shared 使用什么型別來分配記憶體?
std::allocate_shared將使用副本alloc反彈到一個未指定的value_type.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/406486.html
標籤:
下一篇:未排序陣列的二元素總和搜索
