Namespaces
Variants

std::bind_front, std::bind_back

De fr.cppreference.net
 
 
Bibliothèque d'utilitaires
Support linguistique
Support de type (types de base, RTTI)
Macros de test de fonctionnalités de la bibliothèque (C++20)
Utilitaires de programme
Fonctions variadiques
Support des coroutines (C++20)
Support des contrats (C++26)
Comparaison à trois voies
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilitaires généraux
Opérateurs relationnels (obsolète en C++20)
 
Objets fonction
Invocation de fonction
(C++17)(C++23)
Objet fonction identité
(C++20)
Enveloppes d'opérateur transparentes
(C++14)
(C++14)
(C++14)
(C++14)  
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)

Anciens lieurs et adaptateurs
(jusqu'à C++17*)
(jusqu'à C++17*)
(jusqu'à C++17*)
(jusqu'à C++17*)
(jusqu'à C++17*)  
(jusqu'à C++17*)
(jusqu'à C++17*)(jusqu'à C++17*)(jusqu'à C++17*)(jusqu'à C++17*)
(jusqu'à C++20*)
(jusqu'à C++20*)
(jusqu'à C++17*)(jusqu'à C++17*)
(jusqu'à C++17*)(jusqu'à C++17*)

(jusqu'à C++17*)
(jusqu'à C++17*)(jusqu'à C++17*)(jusqu'à C++17*)(jusqu'à C++17*)
(jusqu'à C++20*)
(jusqu'à C++20*)
 
Défini dans l'en-tête <functional>
std::bind_front
template< class F, class... Args >
constexpr /* unspecified */ bind_front( F&& f, Args&&... args );
(1) (depuis C++20)
template< auto ConstFn, class... Args >
constexpr /* unspecified */ bind_front( Args&&... args );
(2) (depuis C++26)
std::bind_back
template< class F, class... Args >
constexpr /* unspecified */ bind_back( F&& f, Args&&... args );
(3) (depuis C++23)
template< auto ConstFn, class... Args >
constexpr /* unspecified */ bind_back( Args&&... args );
(4) (depuis C++26)

Les modèles de fonction std::bind_front et std::bind_back génèrent une enveloppe d'appel à transfert parfait qui permet d'invoquer la cible appelable avec ses (1,2) premiers ou (3,4) derniers sizeof...(Args) paramètres liés à args.

1,3) L'enveloppe d'appel contient une copie de l'objet appelable cible f.
2,4) L'enveloppe d'appel ne contient pas de cible appelable (elle est déterminée statiquement).
1) std::bind_front(f, bound_args...)(call_args...) est équivalent à l'expression de
std::invoke(f, bound_args..., call_args...).
2) std::bind_front<ConstFn>(bound_args...)(call_args...) est équivalent à l'expression de
std::invoke(ConstFn, bound_args..., call_args...).
3) std::bind_back(f, bound_args...)(call_args...) est équivalent à l'expression de
std::invoke(f, call_args..., bound_args...).
4) std::bind_back<ConstFn>(bound_args...)(call_args...) est équivalent à l'expression de
std::invoke(ConstFn, call_args..., bound_args...).

Les conditions suivantes doivent être true, sinon le programme est mal formé :

  • (1,3) std::is_constructible_v<std::decay_t<F>, F>,
  • (1,3) std::is_move_constructible_v<std::decay_t<F>>,
  • (2,4) Si decltype(ConstFn) est un pointeur ou un pointeur vers un membre, alors ConstFn n'est pas un pointeur nul,
  • (std::is_constructible_v<std::decay_t<Args>, Args> && ...),
  • (std::is_move_constructible_v<std::decay_t<Args>> && ...).

Paramètres

f - Callable objet (fonction objet, pointeur vers fonction, référence vers fonction, pointeur vers fonction membre, ou pointeur vers donnée membre) qui sera lié à certains arguments
args - liste des arguments à lier aux ( 1,2 ) premiers ou ( 3,4 ) derniers sizeof... ( Args ) paramètres de la cible appelable
Exigences de type
-
std:: decay_t < F > doit satisfaire aux exigences de MoveConstructible .
-
std:: decay_t < Args > ... doit satisfaire aux exigences de MoveConstructible .
-
decltype ( ConstFn ) doit satisfaire aux exigences de Callable .

Valeur de retour

Un objet fonction (le wrapper d'appel) de type T qui n'est pas spécifié, sauf que les types d'objets retournés par deux appels à std::bind_front ou std::bind_back avec les mêmes arguments sont identiques.

Soit bind-partial soit std::bind_front ou std::bind_back .

L'objet retourné possède les propriétés suivantes :

bind-partial type de retour

Objets membres

L'objet retourné se comporte comme s'il contenait :

1,3) Un objet membre fd de type std:: decay_t < F > initialisé par initialisation directe non-liste à partir de std:: forward < F > ( f ) , et
1-4) Un objet std::tuple tup construit avec std:: tuple < std:: decay_t < Args > ... > ( std:: forward < Args > ( args ) ... ) , sauf que le comportement d'affectation de l'objet retourné n'est pas spécifié et les noms sont uniquement à titre d'exposition.

Constructeurs

Le type de retour de bind-partial se comporte comme si ses constructeurs de copie/déplacement effectuaient une copie/déplacement membre par membre. Il est CopyConstructible si tous ses objets membres (spécifiés ci-dessus) sont CopyConstructible , et est MoveConstructible sinon.

Fonction membre operator()

Étant donné un objet G obtenu d'un appel antérieur à ( 1,3 ) bind-partial (f, args...) ou ( 2,4 ) bind-partial <ConstFn>(args...) , lorsqu'une glvalue g désignant G est invoquée dans une expression d'appel de fonction g ( call_args... ) , un appel de l'objet stocké a lieu, comme par :

1) std:: invoke ( g. fd , std :: get < Ns > ( g. tup ) ..., call_args... ) , lorsque bind-partial est std::bind_front ,
2) std:: invoke ( ConstFn, std :: get < Ns > ( g. tup ) ..., call_args... ) , lorsque bind-partial est std::bind_front ,
3) std:: invoke ( g. fd , call_args..., std :: get < Ns > ( g. tup ) ... ) , lorsque bind-partial est std::bind_back ,
4) std:: invoke ( ConstFn, call_args..., std :: get < Ns > ( g. tup ) ... ) , lorsque bind-partial est std::bind_back ,

  • Ns est un pack d'entiers 0, 1, ..., (sizeof...(Args) - 1) ,
  • g est une lvalue dans l'expression std::invoke si c'est une lvalue dans l'expression d'appel, et est une rvalue sinon. Ainsi std :: move ( g ) ( call_args... ) peut déplacer les arguments liés dans l'appel, alors que g ( call_args... ) copierait.

Le programme est mal formé si g a un type qualifié volatile.

Le membre operator ( ) est noexcept si l'expression std::invoke qu'il appelle est noexcept (en d'autres termes, il préserve la spécification d'exception de l'opérateur d'appel sous-jacent).

Exceptions

1,3) Lance toute exception levée par l'appel au constructeur de l'objet fonction stocké.
1-4) Lance toute exception levée par l'appel du constructeur de l'un des arguments liés.

Notes

Ces modèles de fonction sont destinés à remplacer std::bind . Contrairement à std::bind , ils ne prennent pas en charge la réorganisation arbitraire des arguments et n'ont pas de traitement spécial pour les expressions d'encapsulation imbriquées ou les std::reference_wrapper . En revanche, ils tiennent compte de la catégorie de valeur de l'objet wrapper d'appel et propagent la spécification d'exception de l'opérateur d'appel sous-jacent.

Comme décrit dans std::invoke , lors de l'appel d'un pointeur vers une fonction membre non statique ou d'un pointeur vers un membre de données non statique, le premier argument doit être une référence ou un pointeur (incluant, éventuellement, des pointeurs intelligents tels que std::shared_ptr et std::unique_ptr ) vers un objet dont le membre sera accédé.

Les arguments passés à std::bind_front ou std::bind_back sont copiés ou déplacés, et ne sont jamais passés par référence sauf s'ils sont encapsulés dans std::ref ou std::cref .

Typiquement, lier des arguments à une fonction ou à une fonction membre en utilisant ( 1 ) std::bind_front et ( 3 ) std::bind_back nécessite de stocker un pointeur de fonction ainsi que les arguments, même si le langage sait précisément quelle fonction appeler sans avoir besoin de déréférencer le pointeur. Pour garantir un coût nul dans ces cas, C++26 introduit les versions ( 2,4 ) (qui acceptent l'objet appelable comme argument pour paramètre de modèle constant ).

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_lib_bind_front 201907L (C++20) std::bind_front , ( 1 )
202306L (C++26) Permettre de passer des objets appelables comme arguments template constants à std::bind_front , ( 2 )
__cpp_lib_bind_back 202202L (C++23) std::bind_back , ( 3 )
202306L (C++26) Permettre de passer des objets appelables comme arguments template constants à std::bind_back , ( 4 )

Implémentation possible

(2) bind_front
namespace detail
{
    template<class T, class U>
    struct copy_const
        : std::conditional<std::is_const_v<T>, U const, U> {};
    template<class T, class U,
             class X = typename copy_const<std::remove_reference_t<T>, U>::type>
    struct copy_value_category
        : std::conditional<std::is_lvalue_reference_v<T&&>, X&, X&&> {};
    template <class T, class U>
    struct type_forward_like
        : copy_value_category<T, std::remove_reference_t<U>> {};
    template <class T, class U>
    using type_forward_like_t = typename type_forward_like<T, U>::type;
}
template<auto ConstFn, class... Args>
constexpr auto bind_front(Args&&... args)
{
    using F = decltype(ConstFn);
    if constexpr (std::is_pointer_v<F> ou std::is_member_pointer_v<F>)
        static_assert(ConstFn != nullptr);
    return
        [... bound_args(std::forward<Args>(args))]<class Self, class... T>
        (
            this Self&&, T&&... call_args
        )
        noexcept
        (
            std::is_nothrow_invocable_v<F,
                detail::type_forward_like_t<Self, std::decay_t<Args>>..., T...>
        )
        -> std::invoke_result_t<F,
                detail::type_forward_like_t<Self, std::decay_t<Args>>..., T...>
        {
            return std::invoke(ConstFn, std::forward_like<Self>(bound_args)...,
                               std::forward<T>(call_args)...);
        };
}
(4) bind_back
namespace detail { /* est identique à ci-dessus */ }
template<auto ConstFn, class... Args>
constexpr auto bind_back(Args&&... args)
{
    using F = decltype(ConstFn);
    if constexpr (std::is_pointer_v<F> ou std::is_member_pointer_v<F>)
        static_assert(ConstFn != nullptr);
    return
        [... bound_args(std::forward<Args>(args))]<class Self, class... T>
        (
            this Self&&, T&&... call_args
        )
        noexcept
        (
            std::is_nothrow_invocable_v<F,
                detail::type_forward_like_t<Self, T..., std::decay_t<Args>>...>
        )
        -> std::invoke_result_t<F,
                detail::type_forward_like_t<Self, T..., std::decay_t<Args>>...>
        {
            return std::invoke(ConstFn, std::forward<T>(call_args)...,
                               std::forward_like<Self>(bound_args)...);
        };
}

Exemple

#include <cassert>
#include <functional>
int minus(int a, int b)
{
    return a - b;
}
struct S
{
    int val;
    int minus(int arg) const noexcept { return val - arg; }
};
int main()
{
    auto fifty_minus = std::bind_front(minus, 50);
    assert(fifty_minus(3) == 47); // équivalent à : minus(50, 3) == 47
    auto member_minus = std::bind_front(&S::minus, S{50});
    assert(member_minus(3) == 47); // : S tmp{50}; tmp.minus(3) == 47
    // La spécification noexcept est préservée :
    static_assert(!noexcept(fifty_minus(3)));
    static_assert(noexcept(member_minus(3)));
    // Liaison d'une lambda :
    auto plus = [](int a, int b) { return a + b; };
    auto forty_plus = std::bind_front(plus, 40);
    assert(forty_plus(7) == 47); // équivalent à : plus(40, 7) == 47
#if __cpp_lib_bind_front >= 202306L
    auto fifty_minus_cpp26 = std::bind_front<minus>(50);
    assert(fifty_minus_cpp26(3) == 47);
    auto member_minus_cpp26 = std::bind_front<&S::minus>(S{50});
    assert(member_minus_cpp26(3) == 47);
    auto forty_plus_cpp26 = std::bind_front<plus>(40);
    assert(forty_plus(7) == 47);
#endif
#if __cpp_lib_bind_back >= 202202L
    auto madd = [](int a, int b, int c) { return a * b + c; };
    auto mul_plus_seven = std::bind_back(madd, 7);
    assert(mul_plus_seven(4, 10) == 47); // : madd(4, 10, 7) == 47
#endif
#if __cpp_lib_bind_back >= 202306L
    auto mul_plus_seven_cpp26 = std::bind_back<madd>(7);
    assert(mul_plus_seven_cpp26(4, 10) == 47);
#endif
}

Références

  • Norme C++26 (ISO/IEC 14882:2026) :
  • À déterminer - Modèles de fonction bind_front et bind_back [func.bind.partial]
  • Norme C++23 (ISO/IEC 14882:2024) :
  • 22.10.14 Modèles de fonction bind_front et bind_back [func.bind.partial]
  • Norme C++20 (ISO/CEI 14882:2020) :
  • 20.14.14 Modèle de fonction bind_front [func.bind.front]

Voir aussi

(C++11)
lie un ou plusieurs arguments à un objet fonction
(modèle de fonction)
(C++11)
crée un objet fonction à partir d'un pointeur vers un membre
(modèle de fonction)