std::experimental::not_fn

来自cppreference.com
定义于头文件 <experimental/functional>
template< class F>
/*unspecified*/ not_fn( F&& f );
(库基础 TS v2)

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

参数

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

返回值

FDstd::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>::valuetrue ,则行为未定义。

异常

不抛异常,除非 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::not1std::not2

参阅

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