Date: Thu, 6 Mar 2025 12:50:22 +0100
On 06/03/2025 12.18, Jonathan Wakely via Std-Proposals wrote:
>
>
> On Thu, 6 Mar 2025 at 10:27, Robin Savonen Söderholm via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> Hi!
>
> I recently got burned by a piece of innocent looking code that was something along the lines of this:
> ```c++
> auto [min, max] = std::minmax(a, b - a);
> ```
> The problem stems from the fact that std::minmax (not initialiser_list api) returns a std::pair<T const&, T const&> regardless of what the arguments are AND that the structural bindings 'auto' is just making sure that the object being separated is not a reference, NOT that the objects inside [...] are not references...
> In the best of worlds I would argue that `auto [x, y] = ...` would mean that `x` and `y` are pure values, but I guess such a change could cause trouble due to breaking currently working code that relies on the reference capture (and it would complicate the meaning of `auto& [x, y] = ...`).
> A simpler option would be to change the API for the minmax function (and perhaps other, similar looking functions) to something where if an RValue is detected amongst the arguments, it would return a std::pair<T, T> only (or pair<T const, T const>), while if all arguments are lvalue references it could keep it's current form (for speed or for the need of testing the address of an argument or something..)
>
>
> See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html> which was rejected long ago.
Maybe it's time to reconsider, after 15+ years.
If we can't change the existing interface, we could at least
offer replacements under a different name. Unfortunately,
std::ranges::min/max is already taken, with a proliferation
of the existing interface.
Jens
>
>
> On Thu, 6 Mar 2025 at 10:27, Robin Savonen Söderholm via Std-Proposals <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> Hi!
>
> I recently got burned by a piece of innocent looking code that was something along the lines of this:
> ```c++
> auto [min, max] = std::minmax(a, b - a);
> ```
> The problem stems from the fact that std::minmax (not initialiser_list api) returns a std::pair<T const&, T const&> regardless of what the arguments are AND that the structural bindings 'auto' is just making sure that the object being separated is not a reference, NOT that the objects inside [...] are not references...
> In the best of worlds I would argue that `auto [x, y] = ...` would mean that `x` and `y` are pure values, but I guess such a change could cause trouble due to breaking currently working code that relies on the reference capture (and it would complicate the meaning of `auto& [x, y] = ...`).
> A simpler option would be to change the API for the minmax function (and perhaps other, similar looking functions) to something where if an RValue is detected amongst the arguments, it would return a std::pair<T, T> only (or pair<T const, T const>), while if all arguments are lvalue references it could keep it's current form (for speed or for the need of testing the address of an argument or something..)
>
>
> See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html> which was rejected long ago.
Maybe it's time to reconsider, after 15+ years.
If we can't change the existing interface, we could at least
offer replacements under a different name. Unfortunately,
std::ranges::min/max is already taken, with a proliferation
of the existing interface.
Jens
Received on 2025-03-06 11:50:27