Relax std::move_if_noexcept for std::pair
Jonathan Wakely
jwakely@redhat.com
Fri Dec 21 13:31:00 GMT 2018
On 20/12/18 22:53 +0100, François Dumont wrote:
>On 12/20/18 9:04 AM, Ville Voutilainen wrote:
>>On Thu, 20 Dec 2018 at 08:29, François Dumont <frs.dumont@gmail.com> wrote:
>>>Hi
>>>
>>> I eventually find out what was the problem with the
>>>std::move_if_noexcept within associative containers.
>>>
>>> The std::pair move default constructor might not move both first
>>>and second member. If any is not moveable it will just copy it. And then
>>..as it should..
>>
>>>the noexcept qualification of the copy constructor will participate in
>>>the noexcept qualification of the std::pair move constructor. So
>>>std::move_if_noexcept can eventually decide to not use move because a
>>>_copy_ constructor not noexcept qualified.
>>..and again, as it should.
>>
>>> This is why I am partially specializing __move_if_noexcept_cond. As
>>>there doesn't seem to exist any Standard meta function to find out if
>>>move will take place I resort using std::is_const as in this case for
>>>sure the compiler won't call the move constructor.
>>That seems wrong; just because a type is or is not const has nothing
>>to do whether
>>it's nothrow_move_constructible.
>
>Indeed, I am not changing that.
>
>
>>
>>I don't understand what problem this is solving, and how it's not
>>introducing new problems.
>>
>The problem I am trying to solve is shown by the tests I have adapted.
>Allow more move semantic in associative container where key are stored
>as const.
I'm not convinced that's a desirable property, especially not if it
needs changes to move_if_noexcept.
>But if I make counter_type copy constructor noexcept then I also get
>the move on the pair.second instance, great. I am just surprise to
>have to make a copy constructor noexcept to have std::move_if_noexcept
>work as I expect.
Because the move constructor of pair<const T, U> will copy the first
element not move it, because you can't move from a const object. If
the T(const T&) constructor is noexcept, and the U(U&&) constructor is
also noexcept, then the pair<const T, U> move constructor is noexcept.
The move constructor's exception specification depends on the
exception specifications of whichever constructors it invokes for its
members.
>I think I just need to understand why we need std::move_if_noexcept in
>unordered containers or even rb_tree. Couldn't we just use std::move ?
No. If moving can throw then we can't provide strong exception safety.
>I don't understand what we are trying to avoid with this noexcept
>check.
Then maybe stop trying to change how it works :-)
More information about the Libstdc++
mailing list