std::experimental::not_fn(3)
π std::experimental::not_fn β a C++ Standard Library page, bestie
okay so picture this: you're deep in the std::experimental namespace (yes, that one), you've got a callable, and you literally just want the opposite of it. that's this function. it lives on the manual page std::experimental::not_fn(3) and it is, no cap, kind of iconic. π
β¨ NAME β¨
std::experimental::not_fn β std::experimental::not_fn (she contains multitudes, but the name is the name)
β¨ Synopsis β¨
she's defined in the header <experimental/functional>, and here's the whole vibe:
template< class F> (library fundamentals TS v2)
/*unspecified*/ not_fn( F&& f );
what she does, in one breath: creates a forwarding call wrapper that returns the complement of the callable object it holds. β¨ complement = the ! of it. the "not" of it. iykyk.
πΈ Parameters πΈ
fβ the object from which the Callable object held by the wrapper is constructed π«Ά
π Return value π
okay this part is a little wordy but stay with me, it's worth it.
Let FD be std::decay_t<F> and fd be an lvalue of type FD constructed from std::forward<F>(f).
not_fn returns a forwarding call wrapper fn of unspecified type such that fn(a1, a2, ..., aN) is equivalent to !INVOKE(fd, a1, ..., aN), where INVOKE is the operation described in Callable.
The returned call wrapper is always MoveConstructible, and is CopyConstructible if FD is CopyConstructible. slay. π
π¦ Remarks π¦
bestie. listen. iffdis not Callable, orstd::is_constructible<FD, F>::valueis nottrue, the behavior is undefined. not "a little weird", not "probably fine" β undefined. don't do it. π
π Exceptions π
Throws no exceptions, unless the construction of fd throws. that's it, that's the whole drama. (the only thing that can ruin the vibe is fd's own constructor being messy.)
π Possible implementation π
here's like, one way you could do it. it's giving "here's the blueprint, don't @ me":
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)...);
}
// cv-qualified overload for QoI
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) }; }
like, four cv-qualified operator() overloads because quality-of-implementation said so and honestly? she understood the assignment. β
π§ Notes π§
not_fn is intended to replace the C++03-era negators std::not1 and std::not2. yes, those old ones. they had their era, we're moving on, no hard feelings, periodt. π
π See also π
not_fn(C++17)β creates a function object that returns the complement of the result of the function object it holds (function template) π₯
and that's the page, bestie!! source + version + date, as promised, all cute and accounted for: this came to you from http://cppreference.com, dated 2024.06.10, and the page itself is std::experimental::not_fn(3). go forth and negate your callables responsibly. πβ¨π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms