https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102116
Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |arthur.j.odwyer at gmail dot
com
--- Comment #7 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> ---
(Author of P2266 Simpler Implicit Move here.) As of C++23, the standard is
clear that structured bindings do *not* count as "implicitly movable entities,"
because they're not variables. So GCC's behavior here is non-conforming.
Personally I think GCC's behavior is _reasonable_, and maybe you want to keep
it that way and exert pressure on EWG to make other compilers conform to GCC's
behavior instead of the other way around, but... :)
Reduced test case:
https://godbolt.org/z/dfcT74b7h
#include <tuple>
struct MoveOnly {
MoveOnly();
MoveOnly(MoveOnly&&);
};
struct Bindable {
MoveOnly m;
};
template<> struct std::tuple_element<0, Bindable> { using type = MoveOnly; };
template<> struct std::tuple_size<Bindable> { static constexpr int value = 1;
};
template<int> MoveOnly&& get(Bindable&& b) { return
static_cast<MoveOnly&&>(b.m); }
MoveOnly g() {
auto [m] = Bindable();
return m;
}
GCC permits that `return m;` to compile, by treating `m` as an rvalue; but
everyone else (and the paper standard) agrees that it should not compile.
Interestingly, GCC will also reject if you change the getter to:
template<int> MoveOnly& get(Bindable&& b) { return b.m; }