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; }