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?

Reply via email to