std::bind(3)

NAME
std::bind - std::bind

Synopsis
   Defined in header <functional>
   template< class F, class... Args > (since C++11)
   /*unspecified*/ bind( F&& f, Args&&... args ); (until C++20)
   template< class F, class... Args >
   constexpr /*unspecified*/ bind( F&& f, Args&&... (since C++20)
   args ); (1)
   template< class R, class F, class... Args > (since C++11)
   /*unspecified*/ bind( F&& f, Args&&... args ); (until C++20)
   template< class R, class F, class... Args > (2)
   constexpr /*unspecified*/ bind( F&& f, Args&&... (since C++20)
   args );
   The function template bind generates a forwarding call wrapper for f. Calling this
   wrapper is equivalent to invoking f with some of its arguments bound to args.

Parameters
          Callable object (function object, pointer to function, reference to function,
   f - pointer to member function, or pointer to data member) that will be bound to
          some arguments
   args - list of arguments to bind, with the unbound arguments replaced by the
          placeholders _1, _2, _3... of namespace std::placeholders

Return value
   A function object of unspecified type T, for which std::is_bind_expression<T>::value
   == true. It has the following members: std::bind return type

Member objects
   The return type of std::bind holds a member object of type std::decay<F>::type
   constructed from std::forward<F>(f), and one object per each of args..., of type
   std::decay<Arg_i>::type, similarly constructed from std::forward<Arg_i>(arg_i).
    Constructors
   The return type of std::bind is CopyConstructible if all of its member objects
   (specified above) are CopyConstructible, and is MoveConstructible otherwise. The
   type defines the following members:

Member type result_type
   1) (deprecated in C++17) If F is a pointer to function or a pointer to
   member function, result_type is the return type of F. If F is a class (until C++20)
   type with nested typedef result_type, then result_type is
   F::result_type. Otherwise no result_type is defined.
   2) (deprecated in C++17) result_type is exactly R.

Member function operator()
   Given an object g obtained from an earlier call to bind, when it is invoked in a
   function call expression g(u1, u2, ... uM), an invocation of the stored object takes
   place, as if by
   1) INVOKE(fd, std::forward<V1>(v1), std::forward<V2>(v2), ...,
   std::forward<VN>(vN)), or
   2) INVOKE<R>(fd, std::forward<V1>(v1), std::forward<V2>(v2), ...,
   std::forward<VN>(vN)),
   where INVOKE is the operation specified in Callable, fd is a value of type
   std::decay<F>::type the values and types of the bound arguments v1, v2, ..., vN are
   determined as specified below.
     * If the stored argument arg is of type std::reference_wrapper<T> (for example,
       std::ref or std::cref was used in the initial call to bind), then the argument
       vn in the INVOKE operation above is arg.get() and the type Vn in the same call
       is T&: the stored argument is passed by reference into the invoked function
       object.
     * If the stored argument arg is of type T for which
       std::is_bind_expression<T>::value == true (for example, another bind expression
       was passed directly into the initial call to bind), then bind performs function
       composition: instead of passing the function object that the bind subexpression
       would return, the subexpression is invoked eagerly, and its return value is
       passed to the outer invokable object. If the bind subexpression has any
       placeholder arguments, they are shared with the outer bind (picked out of u1,
       u2, ...). Specifically, the argument vn in the INVOKE operation above is
       arg(std::forward<Uj>(uj)...) and the type Vn in the same call is
       std::result_of<T cv &(Uj&&...)>::type&&
       (until C++17)
       std::invoke_result_t<T cv &, Uj&&...>&&
       (since C++17) (cv qualification is the same as that of g).
     * If the stored argument arg is of type T, for which std::is_placeholder<T>::value
       != 0 (meaning, a placeholder such as std::placeholders::_1, _2, _3, ... was used
       as the argument to the initial call to bind), then the argument indicated by the
       placeholder (u1 for _1, u2 for _2, etc) is passed to the invokable object: the
       argument vn in the INVOKE operation above is std::forward<Uj>(uj) and the
       corresponding type Vn in the same call is Uj&&.
     * Otherwise, the ordinary stored argument arg is passed to the invokable object as
       lvalue argument: the argument vn in the INVOKE operation above is simply arg and
       the corresponding type Vn is T cv &, where cv is the same cv-qualification as
       that of g.
   If some of the arguments that are supplied in the call to g() are not matched by any
   placeholders stored in g, the unused arguments are evaluated and discarded.
   An invocation of operator() is non-throwing
   or is a constant subexpression
   (since C++20) if and only if so is the underlying INVOKE operation. operator()
   participates in overload resolution only if the INVOKE operation is well-formed when
   treated as an unevaluated operand.
   If g is volatile-qualified (i.e., its cv-qualifiers are either volatile or const
   volatile), the program is ill-formed.

Exceptions
   Only throws if construction of std::decay<F>::type from std::forward<F>(f) throws,
   or any of the constructors for std::decay<Arg_i>::type from the corresponding
   std::forward<Arg_i>(arg_i) throws where Arg_i is the ith type and arg_i is the ith
   argument in Args... args.

Notes
   As described in Callable, when invoking a pointer to non-static member function or
   pointer to non-static data member, the first argument has to be a reference or
   pointer (including, possibly, smart pointer such as std::shared_ptr and
   std::unique_ptr) to an object whose member will be accessed.
   The arguments to bind are copied or moved, and are never passed by reference unless
   wrapped in std::ref or std::cref.
   Duplicate placeholders in the same bind expression (multiple _1's for example) are
   allowed, but the results are only well defined if the corresponding argument (u1) is
   an lvalue or non-movable rvalue.

Example
// Run this code
 #include <random>
 #include <iostream>
 #include <memory>
 #include <functional>
 void f(int n1, int n2, int n3, const int& n4, int n5)
 {
     std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
 }
 int g(int n1)
 {
     return n1;
 }
 struct Foo {
     void print_sum(int n1, int n2)
     {
         std::cout << n1+n2 << '\n';
     }
     int data = 10;
 };
 int main()
 {
     using namespace std::placeholders; // for _1, _2, _3...
     std::cout << "1) argument reordering and pass-by-reference: ";
     int n = 7;
     // (_1 and _2 are from std::placeholders, and represent future
     // arguments that will be passed to f1)
     auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
     n = 10;
     f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
                     // makes a call to f(2, 42, 1, n, 7)
     std::cout << "2) achieving the same effect using a lambda: ";
     n = 7;
     auto lambda = [ncref=std::cref(n), n=n](auto a, auto b, auto /*unused*/) {
         f(b, 42, a, ncref, n);
     };
     n = 10;
     lambda(1, 2, 1001); // same as a call to f1(1, 2, 1001)
     std::cout << "3) nested bind subexpressions share the placeholders: ";
     auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
     f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
     std::cout << "4) bind a RNG with a distribution: ";
     std::default_random_engine e;
     std::uniform_int_distribution<> d(0, 10);
     auto rnd = std::bind(d, e); // a copy of e is stored in rnd
     for(int n=0; n<10; ++n)
         std::cout << rnd() << ' ';
     std::cout << '\n';
     std::cout << "5) bind to a pointer to member function: ";
     Foo foo;
     auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
     f3(5);
     std::cout << "6) bind to a mem_fn that is a pointer to member function: ";
     auto ptr_to_print_sum = std::mem_fn(&Foo::print_sum);
     auto f4 = std::bind(ptr_to_print_sum, &foo, 95, _1);
     f4(5);
     std::cout << "7) bind to a pointer to data member: ";
     auto f5 = std::bind(&Foo::data, _1);
     std::cout << f5(foo) << '\n';
     std::cout << "8) bind to a mem_fn that is a pointer to data member: ";
     auto ptr_to_data = std::mem_fn(&Foo::data);
     auto f6 = std::bind(ptr_to_data, _1);
     std::cout << f6(foo) << '\n';
     std::cout << "9) use smart pointers to call members of the referenced objects: ";
     std::cout << f6(std::make_shared<Foo>(foo)) << ' '
               << f6(std::make_unique<Foo>(foo)) << '\n';
 }

Output:
 1) argument reordering and pass-by-reference: 2 42 1 10 7
 2) achieving the same effect using a lambda: 2 42 1 10 7
 3) nested bind subexpressions share the placeholders: 12 12 12 4 5
 4) bind a RNG with a distribution: 0 1 8 5 5 2 0 7 7 10
 5) bind to a pointer to member function: 100
 6) bind to a mem_fn that is a pointer to member function: 100
 7) bind to a pointer to data member: 10
 8) bind to a mem_fn that is a pointer to data member: 10
 9) use smart pointers to call members of the referenced objects: 10 10

See also
   bind_front bind a variable number of arguments, in order, to a function
   bind_back object
   (C++20) (function template)
   (C++23)
   _1, _2, _3, _4, ... placeholders for the unbound arguments in a std::bind expression
   (C++11) (constant)
   mem_fn creates a function object out of a pointer to a member
   (C++11) (function template)