Home > Back-end >  Why do C allocator requirements not require that construct() constructs an object of value_type?
Why do C allocator requirements not require that construct() constructs an object of value_type?

Time:04-09

I found this strange while I was reading this. It says value_type equals to T, but construct() constructs an object of type X, which has nothing to do with T.
However, reference page of std::vector only says

An allocator that is used to acquire/release memory and to construct/destroy the elements in that memory. The type must meet the requirements of Allocator. The behavior is undefined (until C 20)The program is ill-formed (since C 20) if Allocator::value_type is not the same as T.

so I thought that this means I can use any Allocator for std::vector<T, Allocator> if Allocator meets the requirements of Allocator and Allocator::value_type is same as T.
But if what Allocator::construct() really constructs is not Allocator::value_type, how can std::vector's implementation constructs the element of std::vector?

Edit: Well, std::vector's implementation can just use 'placement new', but then what is this Allocator::construct() all about? If it is not meant to be used in such situations like constructing elements of STL containers, in what kinds of situation is it really meant to be used?

CodePudding user response:

Note that a.construct(xp, args) is only optional. A std::vector merely needs allocate() to allocate memory and then it can use placement-new to construct objects in that memory. If the allocator has construct() then the vector can use it to create objects (also of type T) in memory previously obtained via allocate().

a.allocate:

Allocates storage suitable for an array object of type T[n] and creates the array, but does not construct array elements. May throw exceptions.

And returns a pointer to allocated memory.


I think I don't understand. X can be any type including T. Isn't that mean X can be something that is not T, so vector cannot use construct if the allocator it uses have X which is not equal to T?

No. The list is "Given..." and has the bullet:

  • xp, a dereferenceable pointer to some cv-unqualified object type X

That is, you, the caller, picks some X. Then the allocator has to meet the requirement that a.construct(xp, args) constructs an object of type X. What X actually is, that is not specified, hence whatever xp with type X you choose, the allocator has to meet that (optional) requirement.


As an analogon, consider someone writes some multiplication method and the requirement is:

Given some x and y of type int:

  • the method returns the result of x*y.

Now, "some x and y of type int" is what you choose, while "the method returns the result of x*y" is the requirement the method has to fulfill. It's not the method that chooses some x and some y and returns 42 always, because there are values x==1 and y==42 where it yields correct results. Rather, it means that for any x and any y you choose, the method should fullfill "the method returns the result of x*y" (for sake of simplicity, I ignored overflow here).

  • Related