Berikut adalah dokumentasi tentang cppreference , berikut adalah working draftnya.
Saya harus mengakui bahwa saya tidak mengerti apa tujuan sebenarnya polymorphic_allocator
dan kapan / mengapa / bagaimana saya harus menggunakannya.
Sebagai contoh, pmr::vector
memiliki tanda tangan berikut:
namespace pmr {
template <class T>
using vector = std::vector<T, polymorphic_allocator<T>>;
}
Apa polymorphic_allocator
tawarannya? Apa yang std::pmr::vector
ditawarkan juga dalam hal kuno std::vector
? Apa yang dapat saya lakukan sekarang yang tidak dapat saya lakukan sampai sekarang?
Apa tujuan sebenarnya dari pengalokasi itu dan kapan saya harus menggunakannya sebenarnya?
allocator<T>
secara inheren dimilikinya. Jadi, Anda akan melihat nilainya jika Anda sering menggunakan pengalokasi.Jawaban:
Kutipan pilihan dari cppreference:
Masalah dengan pengalokasi "biasa" adalah bahwa mereka mengubah jenis penampung. Jika Anda menginginkan
vector
dengan pengalokasi khusus, Anda dapat menggunakanAllocator
parameter template:Masalahnya sekarang adalah bahwa vektor ini tidak memiliki tipe yang sama dengan vektor dengan pengalokasi berbeda. Anda tidak dapat meneruskannya ke fungsi yang membutuhkan vektor pengalokasi default, misalnya, atau menetapkan dua vektor dengan jenis pengalokasi berbeda ke variabel / penunjuk yang sama, misalnya:
Pengalokasi polimorfik adalah jenis pengalokasi tunggal dengan anggota yang dapat menentukan perilaku pengalokasi melalui pengiriman dinamis daripada melalui mekanisme templat. Ini memungkinkan Anda memiliki penampung yang menggunakan alokasi khusus dan disesuaikan, tetapi masih berjenis umum.
Kustomisasi perilaku pengalokasi dilakukan dengan memberikan pengalokasi
std::memory_resource *
:Masalah utama yang tersisa, seperti yang saya lihat, adalah bahwa
std::pmr::
wadah masih tidak kompatibel denganstd::
wadah yang setara menggunakan pengalokasi default. Anda perlu membuat beberapa keputusan pada saat Anda mendesain antarmuka yang berfungsi dengan penampung:Solusi template memungkinkan pengalokasi apa pun , termasuk pengalokasi polimorfik, tetapi memiliki kelemahan lain (ukuran kode yang dihasilkan, waktu kompilasi, kode harus diekspos dalam file header, potensi untuk "kontaminasi jenis" lebih lanjut yang terus mendorong masalah ke luar). Solusi pengalokasi polimorfik di sisi lain menentukan bahwa pengalokasi polimorfik harus digunakan. Ini menghalangi penggunaan
std::
penampung yang menggunakan pengalokasi default, dan mungkin berimplikasi untuk berinteraksi dengan kode lama.Dibandingkan dengan pengalokasi biasa, pengalokasi polimorfik memang memiliki beberapa biaya kecil, seperti overhead penyimpanan penunjuk memory_resource (yang kemungkinan besar dapat diabaikan) dan biaya pengiriman fungsi virtual untuk alokasi. Masalah utama, sebenarnya, mungkin kurangnya kompatibilitas dengan kode lama yang tidak menggunakan pengalokasi polimorfik.
sumber
std::pmr::
kelas sangat mungkin berbeda?reinterpret_cast
mengikuti antarastd::vector<X>
danstd::pmr::vector<X>
, jika itu yang Anda tanyakan.std::pmr::
kontainer masih tidak kompatibel denganstd::
kontainer yang setara menggunakan pengalokasi default" . Tidak ada operator penugasan yang ditentukan dari satu ke yang lain. Jika ragu, cobalah: godbolt.org/z/Q5BKev (kode tidak persis seperti di atas karena gcc / clang memiliki kelas alokasi polimorfik dalam namespace "percobaan").template<class OtherA, std::enable_if< A can be constructed from OtherA > vector( vector<T, OtherA>&& )
konstruktor. Saya tidak yakin, dan tidak tahu di mana menemukan kompiler yang memiliki pmr yang memenuhi TS.polymorphic_allocator
adalah ke pengalokasi khusus seperti halnyastd::function
panggilan fungsi langsung.Ini hanya memungkinkan Anda menggunakan pengalokasi dengan penampung Anda tanpa harus memutuskan, pada titik deklarasi, yang mana. Jadi jika Anda memiliki situasi di mana lebih dari satu pengalokasi akan sesuai, Anda dapat menggunakan
polymorphic_allocator
.Mungkin Anda ingin menyembunyikan pengalokasi mana yang digunakan untuk menyederhanakan antarmuka Anda, atau mungkin Anda ingin menukarnya dengan kasus runtime yang berbeda.
Pertama Anda membutuhkan kode yang membutuhkan pengalokasi, kemudian Anda harus ingin menukar mana yang digunakan, sebelum mempertimbangkan vektor pmr.
sumber
Salah satu kelemahan pengalokasi polimorfik
polymorphic_allocator<T>::pointer
adalah selalu adilT*
. Itu berarti Anda tidak dapat menggunakannya dengan petunjuk mewah . Jika Anda ingin melakukan sesuatu seperti menempatkan elemen avector
dalam memori bersama dan mengaksesnya melaluiboost::interprocess::offset_ptr
s , Anda perlu menggunakan pengalokasi non-polimorfik biasa untuk itu.Jadi, meskipun pengalokasi polimorfik memungkinkan Anda memvariasikan perilaku alokasi tanpa mengubah jenis statis penampung, pengalokasi tersebut membatasi alokasi .
sumber