unique_ptr, default_delete und allocator
-
Hi!
Ausgangslage:
class foobar { ... }; std::unique_ptr<foobar> factory() { return new foobar; }
Ich möchte dem Nutzer nun Kontrolle darüber geben, wie/wo der Speicher für eine foobar-Instanz angelegt werden soll. Am liebsten hätte ich so etwas in der Art:
template <template <typename> class Alloc> std::unique_ptr<foobar, std::allocator_traits<Alloc<foobar>>::deleter_type> factory(Alloc<foobar>& a) { using traits = std::allocator_traits<Alloc<foobar>>; auto mem = traits::allocate(a, 1); traits::construct(a, mem); return { mem, traits::deleter_type(a) }; }
Ich suche quasi irgendeinen Zusammenhang zwischen einem Allokator und einem Deleter, hier hypothetisch deleter_type, der bei std::allocator der std::default_delete wäre. Gibt es da irgendeine schöne Lösung, ohne dass man der Factory explizit einen Allocator nur für das Anfordern und einen Deleter für das Freigeben von Speicher übergeben muss?
-
Der einem Allokator entsprechende Deleter ist mittels
deallocate
unddestroy
zu implementieren. In C++14 könnte das so aussehen:template <typename Alloc> auto factory(Alloc&& a) { using traits = std::allocator_traits<Alloc>; static_assert(std::is_same<typename traits::value_type, foobar>{}, "Invalid allocator!"); auto del = [a = std::forward<Alloc>(a)] (auto p) mutable { traits::destroy(a, p); traits::deallocate(a, p, 1); }; auto mem = traits::allocate(a, 1); try {traits::construct(a, mem);} catch (...) { traits::deallocate(a, mem, 1); throw;} return std::unique_ptr<typename traits::value_type, decltype(del)>{mem, std::move(del)}; }
(ungetestet)