# std::experimental::not_fn

< cpp‎ | experimental

定义于头文件 `<experimental/functional>` |  |
template< class F> /*unspecified*/ not_fn( F&& f ); |  | (库基础 TS v2)

创建转发调用包装器，它返回其所保有的可调用对象的逻辑补。

### 参数

f | - | 对象，从该对象构造包装器所保有的可调用 (Callable) 对象

### 返回值

令 `FD` 为 std::decay_t<F> ， `fd` 为从 std::forward<F>(f) 构造的 `FD` 类型左值。

则 `not_fn` 返回未指定类型的转发调用包装器，使得 fn(a1, a2, ..., aN) 等价于 !INVOKE(fd, a1, ..., aN) ，其中 `INVOKE` 是 可调用 (Callable) 中描述的操作。

返回的调用包装器始终为可移动构造 (MoveConstructible) ，而若 FD 为可复制构造 (CopyConstructible) 则它亦为可复制构造 (CopyConstructible) 。

### 提醒

若 `fd` 非可调用 (Callable) ，或 std::is_constructible<FD, F>::value 非 `true` ，则行为未定义。

### 异常

不抛异常，除非 `fd` 的构造抛出。

### 可能的实现

    namespace detail {
        template<class F>
        struct not_fn_t {
            F f;
            template<class... Args>
            auto operator()(Args&&... args)
                noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
                -> decltype(!std::invoke(f, std::forward<Args>(args)...)) {
                return !std::invoke(f, std::forward<Args>(args)...);
            }

            // QoI 的 cv 限定重载
            template<class... Args>
            auto operator()(Args&&... args) const
                noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
                -> decltype(!std::invoke(f, std::forward<Args>(args)...)) {
                return !std::invoke(f, std::forward<Args>(args)...);
            }

            template<class... Args>
            auto operator()(Args&&... args) volatile
                noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
                -> decltype(!std::invoke(f, std::forward<Args>(args)...)) {
                return !std::invoke(f, std::forward<Args>(args)...);
            }
            template<class... Args>
            auto operator()(Args&&... args) const volatile
                noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
                -> decltype(!std::invoke(f, std::forward<Args>(args)...)) {
                return !std::invoke(f, std::forward<Args>(args)...);
            }
        };
    }

    template<class F>
    detail::not_fn_t<std::decay_t<F>> not_fn(F&& f) { return { std::forward<F>(f) }; }

### 注意

`not_fn` 的用意是替换 C++03 时代的取反器 std::not1 和 std::not2 。

### 参阅

not_fn (C++17) | 创建返回其保有的函数对象的结果之补的函数对象 (函数模板)