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.