0

Is there a way, having one allocator object for type T, to use the SAME object to allocate memory for any other type. Maybe some magic with static_cast or rebind can help? Because right now I only have an idea of how to use rebind to derive the allocator type for the desired object type from the original allocator, but I don't understand how to use a ready-made allocator object to create any type of object.

  • 1
    A particular allocator object only knows how to allocate a particular type: namely, `std::allocator_traits::value_type`. You need to construct a new rebound allocator object capable of allocating a different type: `std::allocator_traits::rebind_alloc new_alloc(original_alloc);` – Igor Tandetnik Oct 10 '22 at 14:39
  • @IgorTandetnik I had that thought because I saw a template copy constructor for the same std::allocator, but if I copy e.g. pool allocator, won't that allocate new memory? Will the pool then be shared between the two objects? – Ian Gaspariunas Oct 10 '22 at 14:48
  • If you pool allocator has unique ownership of the pool, yes. If it shares ownership or references an existing pool, no – Caleth Oct 10 '22 at 14:50
  • FYI: `template std::allocator::allocator(const std::allocator&)` isn't a copy constructor. The implicit copy constructor wins overload resolution if `U` deduces to `T` – Caleth Oct 10 '22 at 14:53
  • @Caleth Yes, of course, I said silly) – Ian Gaspariunas Oct 10 '22 at 14:55
  • @user17732522 I was just wondering whether the standard requires this behavior or not. Thank you ! – Ian Gaspariunas Oct 10 '22 at 15:00
  • @IanGaspariunas Sorry, what I wrote isn't really correct. I will write it properly in an answer. – user17732522 Oct 10 '22 at 15:02

1 Answers1

1

An allocator a of type A for value type T conforming to the standard requirements can be rebound to an allocator for type U via e.g.

std::allocator_traits<A>::rebind_alloc<U> b(a);

(although an allocator may support only a subset of all possible types U and fail to instantiate with others)

Then b can be used to allocate and deallocate objects of type U. You do not need to store this allocator b in addition to a however. Each time you perform this rebind from the same value of a it is guaranteed that the b objects compare equal, meaning that one can be used to deallocate memory allocated by the other.

Note that I didn't say that correctly in a previous comment: It is not guaranteed that an allocation allocated by a can be deallocated by b. So an allocator may be using e.g. different memory resources for different types, but the memory resources cannot be embedded into the allocator and copied on allocator copy or rebind.

user17732522
  • 53,019
  • 2
  • 56
  • 105