P2447 has been merged in C++26, backport the same functionality.
This makes QSpan<const T> a proper replacement for a const QList<T>&
parameter, because now both can be built via a braced-init-list.
// void f(const QList<int> &l); // old
void f(QSpan<const int>); // new
f({1, 2, 3}); // now OK
This is, technically speaking, SiC: in the presence of both `f`
overloads, the code above would have called the QList one. Now instead
the call is ambiguous.
We've been there already -- this is QString and QStringView all over
again, and the solution is the same: get rid of the owning container
overload. I'd rather have this construction *sooner* rather than *later*
in order to minimize the fallout.
And just like QString vs QStringView, there's nothing really doable to
prevent instant-dangling situations:
QStringView v = getString(); // dangles
QSpan<const int> s = {1, 2, 3}; // ditto
except for using QSpan (QStringView) as a *parameter type only*.
Note that QSpan with dynamic extent was already convertible from
std::initializer_list through its ranged constructor. However this fact
alone doesn't unlock the above syntax. QSpan with a static extent was
also convertible for the same reason. (This is non-standard:
std::span's range constructor for static extents is explicit, but QSpan
doesn't follow that design choice and makes the constructors implicit
instead.)
Found in API-review.
Change-Id: I160ab5b292b0c2568cd9a7ad1b4430085f475c29
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 7f7b5ff3a1b617a3a1add1b1b6ad0718f0dcf143)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>