Namespaces
Variants

std:: not_fn

From cppreference.net
Utilities library
Function objects
Function invocation
(C++17) (C++23)
Identity function object
(C++20)
Old binders and adaptors
( until C++17* )
( until C++17* )
( until C++17* )
( until C++17* )
( until C++17* ) ( until C++17* ) ( until C++17* ) ( until C++17* )
( until C++20* )
( until C++20* )
( until C++17* ) ( until C++17* )
( until C++17* ) ( until C++17* )

( until C++17* )
( until C++17* ) ( until C++17* ) ( until C++17* ) ( until C++17* )
( until C++20* )
( until C++20* )
Défini dans l'en-tête <functional>
template < class F >
/* non spécifié */ not_fn ( F && f ) ;
(1) (depuis C++17)
(constexpr depuis C++20)
template < auto ConstFn >
constexpr /* non spécifié */ not_fn ( ) noexcept ;
(2) (depuis C++26)
1) Crée un wrapper d'appel de transfert qui retourne la négation de l'objet appelable qu'il contient.
2) Crée un wrapper d'appel de transfert qui retourne la négation de la cible appelable déterminée statiquement. Le programme est mal formé si ConstFn est un pointeur nul ou un pointeur-vers-membre nul.

Table des matières

Paramètres

f - l'objet à partir duquel l'objet Callable détenu par le wrapper est construit
Exigences de type
-
std:: decay_t < F > doit satisfaire aux exigences de Callable et MoveConstructible .
-
std:: is_constructible_v < std:: decay_t < F > , F > doit être true .

Valeur de retour

1) A function object of unspecified type T . It has the following members.

std::not_fn type de retour

Objets membres

Le type de retour de std::not_fn contient un objet membre de type std:: decay_t < F > .

Constructeurs

explicit T ( F && f ) ;
(1) (depuis C++17)
(constexpr depuis C++20)
( exposition uniquement* )
T ( T && f ) = default ;
T ( const T & f ) = default ;
(2) (depuis C++17)
1) Le constructeur initialise directement-non-par-liste l'objet membre (de type std:: decay_t < F > ) à partir de std:: forward < F > ( f ) . Lance toute exception levée par le constructeur sélectionné.
2) Parce que std:: decay_t < F > est requis d'être MoveConstructible , le wrapper d'appel retourné est toujours MoveConstructible , et est CopyConstructible si std:: decay_t < F > est CopyConstructible .

Les définitions explicitement par défaut rendent le type de retour non assignable.

(until C++20)

Il n'est pas spécifié si ces constructeurs sont explicitement par défaut et si le type de retour est assignable.

(since C++20)

Fonction membre operator ( )

(1)
template < class ... Args >

auto operator ( ) ( Args && ... args ) &
- > decltype ( ! std:: declval <
std:: invoke_result_t < std:: decay_t < F > & , Args... >> ( ) ) ;
template < class ... Args >
auto operator ( ) ( Args && ... args ) const &
- > decltype ( ! std:: declval <

std:: invoke_result_t < std:: decay_t < F > const & , Args... >> ( ) ) ;
(depuis C++17)
(jusqu'à C++20)
template < class ... Args >

constexpr auto operator ( ) ( Args && ... args ) &
noexcept ( /* voir ci-dessous */ )
- > decltype ( ! std:: invoke (
std:: declval < std:: decay_t < F > & > ( ) , std:: declval < Args > ( ) ... ) ) ;
template < class ... Args >
constexpr auto operator ( ) ( Args && ... args ) const &
noexcept ( /* voir ci-dessous */ )
- > decltype ( ! std:: invoke (

std:: declval < std:: decay_t < F > const & > ( ) , std:: declval < Args > ( ) ... ) ) ;
(depuis C++20)
(2)
template < class ... Args >

auto operator ( ) ( Args && ... args ) &&
- > decltype ( ! std:: declval <
std:: invoke_result_t < std:: decay_t < F > , Args... >> ( ) ) ;
template < class ... Args >
auto operator ( ) ( Args && ... args ) const &&
- > decltype ( ! std:: declval <

std:: invoke_result_t < std:: decay_t < F > const , Args... >> ( ) ) ;
(depuis C++17)
(jusqu'à C++20)
template < class ... Args >

constexpr auto operator ( ) ( Args && ... args ) &&
noexcept ( /* voir ci-dessous */ )
- > decltype ( ! std:: invoke (
std:: declval < std:: decay_t < F >> ( ) , std:: declval < Args > ( ) ... ) ) ;
template < class ... Args >
constexpr auto operator ( ) ( Args && ... args ) const &&
noexcept ( /* voir ci-dessous */ )
- > decltype ( ! std:: invoke (

std:: declval < std:: decay_t < F > const > ( ) , std:: declval < Args > ( ) ... ) ) ;
(depuis C++20)

Soit fd l'objet membre de type std:: decay_t < F > .

1) Équivalent à return ! std:: invoke ( fd, std:: forward < Args > ( args ) ... ) ;
2) Équivalent à return ! std:: invoke ( std :: move ( fd ) , std:: forward < Args > ( args ) ... ) ;

Lors de l'appel du résultat, si la substitution dans le type de retour de la surcharge d'opérateur operator ( ) initialement sélectionnée échoue, une autre surcharge peut être sélectionnée .

(depuis C++17)
(jusqu'à C++20)
1) Expression-équivalente à ! std:: invoke ( fd, std:: forward < Args > ( args ) ... )
2) Expression-équivalente à ! std:: invoke ( std :: move ( fd ) , std:: forward < Args > ( args ) ... )

Lors de l'appel du résultat, si la substitution dans le type de retour de la surcharge d'opérateur operator ( ) initialement sélectionnée échoue, l'appel est mal formé, ce qui peut également être une échec de substitution .

(depuis C++20)
2) Une valeur du type suivant.

std::not_fn type de retour sans état

Le type de retour est une CopyConstructible classe sans état. Il n'est pas spécifié si le type de retour est assignable.

Fonction membre operator ( )

template < class ... Args >

constexpr auto operator ( ) ( Args && ... args ) const
noexcept ( /* voir ci-dessous */ )

- > decltype ( ! std:: invoke ( ConstFn, std:: declval < Args > ( ) ... ) ) ;
(depuis C++26)

Équivalent d'expression à ! std:: invoke ( ConstFn, std:: forward < Args > ( args ) ... ) .

Exceptions

1) Ne lance aucune exception, sauf si la construction de fd lance une exception.

Implémentation possible

**Note:** Le code C++ n'a pas été traduit conformément aux instructions, car il se trouve dans des balises `
` et contient des termes spécifiques au C++. Seule la structure HTML a été préservée sans modification du contenu du code.
(1) not_fn
namespace detail
{
    template<class V, class F, class... Args>
    constexpr bool negate_invocable_impl = false;
    template<class F, class... Args>
    constexpr bool negate_invocable_impl<std::void_t<decltype(
        !std::invoke(std::declval<F>(), std::declval<Args>()...))>, F, Args...> = true;
    template<class F, class... Args>
    constexpr bool negate_invocable_v = negate_invocable_impl<void, F, Args...>;
    template<class F>
    struct not_fn_t
    {
        F f;
        template<class... Args,
            std::enable_if_t<negate_invocable_v<F&, Args...>, int> = 0>
        constexpr decltype(auto) operator()(Args&&... args) &
            noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
        {
            return !std::invoke(f, std::forward<Args>(args)...);
        }
        template<class... Args,
            std::enable_if_t<negate_invocable_v<const F&, Args...>, int> = 0>
        constexpr decltype(auto) operator()(Args&&... args) const&
            noexcept(noexcept(!std::invoke(f, std::forward<Args>(args)...)))
        {
            return !std::invoke(f, std::forward<Args>(args)...);
        }
        template<class... Args,
            std::enable_if_t<negate_invocable_v<F, Args...>, int> = 0>
        constexpr decltype(auto) operator()(Args&&... args) &&
            noexcept(noexcept(!std::invoke(std::move(f), std::forward<Args>(args)...)))
        {
            return !std::invoke(std::move(f), std::forward<Args>(args)...);
        }
        template<class... Args,
            std::enable_if_t<negate_invocable_v<const F, Args...>, int> = 0>
        constexpr decltype(auto) operator()(Args&&... args) const&&
            noexcept(noexcept(!std::invoke(std::move(f), std::forward<Args>(args)...)))
        {
            return !std::invoke(std::move(f), std::forward<Args>(args)...);
        }
        // Les surcharges supprimées sont nécessaires depuis C++20
        // pour empêcher qu'une surcharge non équivalente mais bien formée soit sélectionnée.
        template<class... Args,
            std::enable_if_t<!negate_invocable_v<F&, Args...>, int> = 0>
        void operator()(Args&&...) & = delete;
        template<class... Args,
            std::enable_if_t<!negate_invocable_v<const F&, Args...>, int> = 0>
        void operator()(Args&&...) const& = delete;
        template<class... Args,
            std::enable_if_t<!negate_invocable_v<F, Args...>, int> = 0>
        void operator()(Args&&...) && = delete;
        template<class... Args,
            std::enable_if_t<!negate_invocable_v<const F, Args...>, int> = 0>
        void operator()(Args&&...) const&& = delete;
    };
}
template<class F>
constexpr detail::not_fn_t<std::decay_t<F>> not_fn(F&& f)
{
    return {std::forward<F>(f)};
}
(2) not_fn
namespace detail
{
    template<auto ConstFn>
    struct stateless_not_fn
    {
        template<class... Args>
        constexpr auto operator()(Args&&... args) const
            noexcept(noexcept(!std::invoke(ConstFn, std::forward<Args>(args)...)))
            -> decltype(!std::invoke(ConstFn, std::forward<Args>(args)...))
        {
            return !std::invoke(ConstFn, std::forward<Args>(args)...);
        }
    };
}
template<auto ConstFn>
constexpr detail::stateless_not_fn<ConstFn> not_fn() noexcept
{
    if constexpr (std::is_pointer_v<decltype(ConstFn)> ||
                  std::is_member_pointer_v<decltype(ConstFn)>)
        static_assert(ConstFn != nullptr);
    return {};
}

Notes

std::not_fn est destiné à remplacer les négateurs de l'ère C++03 std::not1 et std::not2 .

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_not_fn 201603L (C++17) std::not_fn() , ( 1 )
202306L (C++26) Permettre de passer des objets appelables comme arguments template constants à std::not_fn , ( 2 )

Exemple

#include <cassert>
#include <functional>
bool is_same(int a, int b) noexcept
{
    return a == b;
}
struct S
{
    int val;
    bool is_same(int arg) const noexcept { return val == arg; }
};
int main()
{
    // Utilisation avec une fonction libre :
    auto is_differ = std::not_fn(is_same);
    assert(is_differ(8, 8) == false); // équivalent à : !is_same(8, 8) == false
    assert(is_differ(6, 9) == true); // équivalent à : !is_same(8, 0) == true
    // Utilisation avec une fonction membre :
    auto member_differ = std::not_fn(&S::is_same);
    assert(member_differ(S{3}, 3) == false); //: S tmp{6}; !tmp.is_same(6) == false
    // La spécification noexcept est préservée :
    static_assert(noexcept(is_differ) == noexcept(is_same));
    static_assert(noexcept(member_differ) == noexcept(&S::is_same));
    // Utilisation avec un objet fonction :
    auto same = [](int a, int b) { return a == b; };
    auto differ = std::not_fn(same);
    assert(differ(1, 2) == true); //: !same(1, 2) == true
    assert(differ(2, 2) == false); //: !same(2, 2) == false
#if __cpp_lib_not_fn >= 202306L
    auto is_differ_cpp26 = std::not_fn<is_same>();
    assert(is_differ_cpp26(8, 8) == false);
    assert(is_differ_cpp26(6, 9) == true);
    auto member_differ_cpp26 = std::not_fn<&S::is_same>();
    assert(member_differ_cpp26(S{3}, 3) == false);
    auto differ_cpp26 = std::not_fn<same>();
    static_assert(differ_cpp26(1, 2) == true);
    static_assert(differ_cpp26(2, 2) == false);
#endif
}

Voir aussi

(obsolète en C++17) (supprimé en C++20)
construit un objet std::unary_negate personnalisé
(modèle de fonction)
(obsolète en C++17) (supprimé en C++20)
construit un objet std::binary_negate personnalisé
(modèle de fonction)