https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111568

            Bug ID: 111568
           Summary: std::not_fn can accept non-movable function
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hewillk at gmail dot com
  Target Milestone: ---

It seems that std::not_fn should reject the following code according to
[func.not.fn]: "Mandates: is_constructible_v<FD, F> &&
is_move_constructible_v<FD> is true."

https://godbolt.org/z/MsrqnbY74

#include <functional>

struct OnlyCopyableFun {
  OnlyCopyableFun() = default;
  OnlyCopyableFun(const OnlyCopyableFun&) = default;
  OnlyCopyableFun(OnlyCopyableFun&&) = delete;
  bool operator()(auto) const;
};

int main() {
  OnlyCopyableFun f;
  auto nf = std::not_fn(f); // only ill-formed in libc++
}

Not quite sure why these standard call wrapper factories (std::bind_front,
std::bind, etc.) require all argument types to be move-constructible, although
the call wrapper produced in the above example is still move-constructible as
its underlying type has a copy constructor.
It seems to me that just requiring is_constructible_v<FD, F> is enough, which
is what the range adaptor object does.

Reply via email to