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

Reply via email to