2

I guess that std::vector uses allocator_traits::construct when it copy/moves the elements into the reallocated buffer.
Then I think that it needs to evaluate whether the function throws or not, to decide the reallocation strategy. but it seems difficult (for me) to do. This would not be a worry if it uses placement new(rather than allocator_traits::construct), std::is_nothrow_move_constructible<value_type> would do the job.

addition :
Let me add some information. I hope this clarify the intention of my question.
My question relates to the mechanism to assure the exception guarantee of a std::vector like container in terms of the reallocation strategy.
Usually, on the reallocation, such container can't move the elements in a code path that may throw if it advertises strong exception guarantee.
Based on the above, there is a thing called AllocatorAwareContainer. And it says

An AllocatorAwareContainer is a Container that holds an instance of an Allocator and uses that instance in all its member functions to allocate and deallocate memory and to construct and destroy objects in that memory

I translated it so that an allocator aware container needs to use allocator_traits::construct when it copy/moves the elements into the reallocated buffer. Thus, the container implementer needs to know whether the function throws or not when it is called in the form of std::allocator_traits<allocator_type>::construct(a, p, std::move(elem)). Important thing here is that allocator_traits::construct is a customization point. So, it may throw even if std::is_nothrow_move_constructible_v<velue_type> is true. Unfortunately, it seems that the function is not qualified as noexcept no matter what it is doing(see), that is, noexcept operator dose not work for this purpose. then the question arises.

update:
I found a related question here.
Acconding to the answer and comments there, there seems to be a defect in the standard. And because of it, std::vector's exception safety is weakened. what we can do now is, only hope so that allocator_traits::construct does not throw exception when std::is_nothrow_move_constructible_v<value_type> is true;

a.tana
  • 41
  • 7
  • 1
    Why do you think `allocator_traits::construct` matters? Its job is to pass the arguments to the appropriate constructor, including potentially the move constructor (meaning `std::is_nothrow_move_constructible` is a perfectly valid check). Have you checked the implementation in gcc or libc++? – Stephen Newell Feb 10 '21 at 02:54
  • Stephen Newell, My thought is that some custom allocators may do something more than calling constructors. – a.tana Feb 10 '21 at 03:08
  • There really isn't much to it. On reallocation, it simply uses something equivalent to [`std::move_if_noexcept`](https://en.cppreference.com/w/cpp/utility/move_if_noexcept) to produce either an rvalue (for move) or const lvalue (for copy) which just calls the constructor via overload resolution. Whether or not this is done through `allocator_traits::construct` is mostly irrelevant – Human-Compiler Feb 10 '21 at 05:06
  • @Human-Compiler, Do you mean that `allocator_traits::construct` is not used on reallocation?. if so, that makes sense somewhat, but is `std::vector` allowed to ignore `allocator_traits::construct`? – a.tana Feb 10 '21 at 06:29

0 Answers0