Date: Thu, 6 Mar 2025 11:23:42 +0100
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..)
What would be the best remedy for things like this you think?
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..)
What would be the best remedy for things like this you think?
Received on 2025-03-06 10:27:11