This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4533. not_fn<f> is unimplementable

Section: 22.10.13 [func.not.fn], 22.10.14 [func.bind.partial] Status: New Submitter: Tim Song Opened: 2026-03-05 Last modified: 2026-03-06

Priority: Not Prioritized

View other active issues in [func.not.fn].

View all other issues in [func.not.fn].

View all issues with New status.

Discussion:

The current specification of not_fn<f> says that the perfect forwarding call wrapper it returns does not have state entities. 22.10.4 [func.require]p8 says that such wrappers "returned by a given standard library function template have the same type if the types of their corresponding state entities are the same." That condition is trivially true.

It follows that not_fn<f>() must return the same type regardless of the value or type of f. This is, as far as I know, impossible to implement, and certainly not the intent.

bind_front<f> and bind_back<f> suffer from the same problem.

Proposed resolution:

This wording is relative to N5032.

  1. Modify 22.10.3 [func.def] as indicated:

    -5- A call wrapper type is a type that holds a target object, which is either a callable object or an object representing a callable object, and supports a call operation that forwards to that callable object.

    -6- […]

    -7- A target object is the callable object held by a call wrapper.

    -8- A call wrapper type may additionally hold a sequence of objects and references that may be passed as arguments to the targetcallable object. These entities are collectively referred to as bound argument entities.

  2. Modify 22.10.13 [func.not.fn] as indicated:

    template<auto f> constexpr unspecified not_fn() noexcept;
    

    -6- […]

    -7- […]

    -8- Returns: A perfect forwarding call wrapper (22.10.4 [func.require]) g that does not have state entities whose target object is a copy of constant_arg<f>, and has thewhose call pattern is !invoke(f, call_args...).

  3. Modify 22.10.14 [func.bind.partial] as indicated:

    template<auto f, class... Args>
      constexpr unspecified bind_front(Args&&... args);
    template<auto f, class... Args>
      constexpr unspecified bind_back(Args&&... args);
    

    -6- […]

    -7- […]

    -8- […]

    -9- Returns: A perfect forwarding call wrapper (22.10.4 [func.require]) g that does not have a target object whose target object is a copy of constant_arg<f>, and has thewhose call pattern is:

    • (2.1) — invoke(f, bound_args..., call_args...) for a bind_front invocation, or

    • (2.2) — invoke(f, call_args..., bound_args...) for a bind_back invocation.