std::bind_f...::bind_back(3)
π NAME π
Okay so bestie, this is the C++ Standard Libary page for std::bind_f...::bind_back(3) β and the manual name line is literally std::bind_front,std::bind_back, followed by std::bind_front,std::bind_back again. Itβs giving βwe said what we saidβ energy π.
β¨ Synopsis β¨
Defined in header <functional>
template< class F, class... Args > (1)
(since C++20)
constexpr /* unspecified */ bind_front( F&& f, Args&&... args );
template< auto ConstFn, class... Args > (2)
(since C++26)
constexpr /* unspecified */ bind_front( Args&&... args );
template< class F, class... Args > (3)
(since C++23)
constexpr /* unspecified */ bind_back( F&& f, Args&&... args );
template< auto ConstFn, class... Args > (4)
(since C++26)
constexpr /* unspecified */ bind_back( Args&&... args );
Function templates std::bind_front and std::bind_back generate a perfect forwarding call wrapper which allows to invoke the callable target with its (1,2) first or (3,4) last sizeof...(Args) parameters bound to args.
- 1,3) The call wrapper holds a copy of the target callable object
f. - 2,4) The call wrapper does not hold a callable target (it is statically determined).
- 1)
std::bind_front(f, bound_args...)(call_args...)is expression-equivalent tostd::invoke(f, bound_args..., call_args...). - 2)
std::bind_front<ConstFn>(bound_args...)(call_args...)is expression-equivalent tostd::invoke(ConstFn, bound_args..., call_args...). - 3)
std::bind_back(f, bound_args...)(call_args...)is expression-equivalent tostd::invoke(f, call_args..., bound_args...). - 4)
std::bind_back<ConstFn>(bound_args...)(call_args...)is expression-equivalent tostd::invoke(ConstFn, call_args..., bound_args...).
The following conditions must be true, otherwise the program is ill-formed:
- (1,3)
std::is_constructible_v<std::decay_t<F>, F>, - (1,3)
std::is_move_constructible_v<std::decay_t<F>>, - (2,4) If
decltype(ConstFn)is a pointer or a pointer-to-member thenConstFnis not a null pointer, - (
std::is_constructible_v<std::decay_t<Args>, Args> && ...), - (
std::is_move_constructible_v<std::decay_t<Args>> && ...).
πΈ Parameters πΈ
Hereβs the tea on the parameters, bestie:
fβ Callable object (function object, pointer to function, reference to function, pointer to member function, or pointer to data member) that will be bound to some arguments.argsβ list of the arguments to bind to the (1,2) first or (3,4) lastsizeof...(Args)parameters of the callable target.
π¦ Type requirements π¦
std::decay_t<F>must meet the requirements ofMoveConstructible.std::decay_t<Args>...must meet the requirements ofMoveConstructible.decltype(ConstFn)must meet the requirements ofCallable.
β Return value β
A function object (the call wrapper) of type T that is unspecified, except that the types of objects returned by two calls to std::bind_front or std::bind_back with the same arguments are the same.
Let bind-partial be either std::bind_front or std::bind_back.
The returned object has the following properties:
bind-partial return type
π§Έ Member objects
The returned object behaves as if it holds:
- 1,3) A member object
fdof typestd::decay_t<F>direct-non-list-initialized fromstd::forward<F>(f), and - 1-4) An
std::tupleobjecttupconstructed withstd::tuple<std::decay_t<Args>...>(std::forward<Args>(args)...), except that the returned objectβs assignment behavior is unspecified and the names are for exposition only.
π Constructors
The return type of bind-partial behaves as if its copy/move constructors perform a memberwise copy/move. It is CopyConstructible if all of its member objects (specified above) are CopyConstructible, and is MoveConstructible otherwise.
π§ Member function operator()
Given an object G obtained from an earlier call to (1,3) bind-partial(f, args...) or (2,4) bind-partial<ConstFn>(args...), when a glvalue g designating G is invoked in a function call expression g(call_args...), an invocation of the stored object takes place, as if by:
std::invoke(g.fd, std::get<Ns>(g.tup)..., call_args...), whenbind-partialisstd::bind_front,std::invoke(ConstFn, std::get<Ns>(g.tup)..., call_args...), whenbind-partialisstd::bind_front,std::invoke(g.fd, call_args..., std::get<Ns>(g.tup)...), whenbind-partialisstd::bind_back,std::invoke(ConstFn, call_args..., std::get<Ns>(g.tup)...), whenbind-partialisstd::bind_back,
where
Nsis an integer pack0, 1, ..., (sizeof...(Args) - 1),gis an lvalue in thestd::invokeexpression if it is an lvalue in the call expression, and is an rvalue otherwise. Thusstd::move(g)(call_args...)can move the bound arguments into the call, whereg(call_args...)would copy.
The program is ill-formed if g has volatile-qualified type.
The member operator() is noexcept if the std::invoke expression it calls is noexcept (in other words, it preserves the exception specification of the underlying call operator).
π Exceptions π
- 1,3) Throw any exception thrown by calling the constructor of the stored function object.
- 1-4) Throw any exception thrown by calling the constructor of any of the bound arguments.
π Notes π
These function templates are intended to replace std::bind. Unlike std::bind, they do not support arbitrary argument rearrangement and have no special treatment for nested bind-expressions or std::reference_wrappers. On the other hand, they pay attention to the value category of the call wrapper object and propagate exception specification of the underlying call operator.
As described in std::invoke, 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 std::bind_front or std::bind_back are copied or moved, and are never passed by reference unless wrapped in std::ref or std::cref.
Typically, binding arguments to a function or a member function using (1) std::bind_front and (3) std::bind_back requires storing a function pointer along with the arguments, even though the language knows precisely which function to call without a need to dereference the pointer. To guarantee βzero costβ in those cases, C++26 introduces the versions (2,4) (that accept the callable object as an argument for non-type template parameter).
Feature-test macro vibe check:
__cpp_lib_bind_frontβ201907Lβ (C++20) βstd::bind_front, (1)__cpp_lib_bind_frontβ202306Lβ (C++26) β Allow passing callable objects as non-type template arguments tostd::bind_front, (2)__cpp_lib_bind_backβ202202Lβ (C++23) βstd::bind_back, (3)__cpp_lib_bind_backβ202306Lβ (C++26) β Allow passing callable objects as non-type template arguments tostd::bind_back, (4)
β¨ EXAMPLE β¨
okay bestie, this is where the code actually does its little dance π β hit Run this code, let the asserts vibe-check everything, and watch bind_front / bind_back do their thing. The #if blocks are just version-gating the shiny C++26 extras, iykyk π
// Run this code
#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); // equivalent to: 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
// Noexcept-specification is preserved:
static_assert(!noexcept(fifty_minus(3)));
static_assert(noexcept(member_minus(3)));
// Binding of a lambda:
auto plus = [](int a, int b) { return a + b; };
auto forty_plus = std::bind_front(plus, 40);
assert(forty_plus(7) == 47); // equivalent to: 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
}
π REFERENCES π
- C++26 standard (
ISO/IEC 14882:2026):TBD Function templates bind_front and bind_back [func.bind.partial]
- C++23 standard (
ISO/IEC 14882:2023):22.10.14 Function templates bind_front and bind_back [func.bind.partial]
- C++20 standard (
ISO/IEC 14882:2020):20.14.14 Function template bind_front [func.bind.front]
π SEE ALSO π
bindβ binds one or more arguments to a function object. (C++11) (function template)mem_fnβ creates a function object out of a pointer to a member. (C++11) (function template)
and thatβs the whole page, bestie π«Ά the footerβs source/version situation is cppreference.com, and the date on it is 2024.06.10 β periodt π
π
π¦ 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