[Bug libstdc++/111550] The range adaptor closure object generated by adaptor(args...) is not a perfect forwarding call wrapper
hewillk at gmail dot com
gcc-bugzilla@gcc.gnu.org
Sun Sep 24 10:14:51 GMT 2023
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111550
--- Comment #3 from 康桓瑋 <hewillk at gmail dot com> ---
Let me report another issue I observed on this PR.
According to [range.adaptor.object], adaptor(args...) uses
std::forward<decltype((args))>(args).. . to forward arguments into the call
wrapper's decayed member, whereas libstdc++ unconditionally uses std::moves,
which causes the following code to be rejected:
https://godbolt.org/z/EYoxzfWKn
#include <ranges>
struct NonMovable {
NonMovable() = default;
NonMovable(const NonMovable&) = default;
NonMovable(NonMovable&&) = delete;
};
int main() {
NonMovable nonmovable;
auto r = std::views::take(nonmovable); // hard error in libc++ and
lidstdc++
}
The libc++ implementation uses std::bind_back, so it will also produce a hard
error because std::bind_back requires that the argument must be
move-constructible.
It seems like only MSVC conforms to the standard's wording.
The standard does not require the type of args... here to be move-constructible
like other call wrapper factories (such as
std::bind_front/std::bind_back/std::bind) do, which seems to introduce some
inconsistencies.
Although I don't think such constraint is necessary, and I don't know if it's
worthy of an LWG?
More information about the Gcc-bugs
mailing list