std::bind_front, std::bind_back
Defined in header <functional>
|
||
std::bind_front |
||
template
<
class F, class... Args
>
constexpr /* unspecified */ bind_front( F&& f, Args&&... args ) ; |
(1) | (since C++20) |
template
<
auto ConstFn, class... Args
>
constexpr /* unspecified */ bind_front( Args&&... args ) ; |
(2) | (since C++26) |
std::bind_back |
||
template
<
class F, class... Args
>
constexpr /* unspecified */ bind_back( F&& f, Args&&... args ) ; |
(3) | (since C++23) |
template
<
auto ConstFn, class... Args
>
constexpr /* unspecified */ bind_back( Args&&... args ) ; |
(4) | (since C++26) |
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
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 then
ConstFn
- ( std::is_constructible_v < std::decay_t <Args>, Args> && ...)
- ( std::is_move_constructible_v < std::decay_t <Args>> && ...)
Parameters
f | - | Callable |
args | - | list of the arguments to bind to the (1,2) first or (3,4) last sizeof...(Args) |
Type requirements | ||
-
std::decay_t<F>
must meet the requirements of MoveConstructible
|
||
-
std::decay_t<Args>...
must meet the requirements of MoveConstructible
|
||
-
decltype(ConstFn) must meet the requirements of Callable
|
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:
fd
of type
std::decay_t<F>
direct-non-list-initialized from
std::forward
<F>
(f)
tup
constructed with
std::tuple
<
std::decay_t
<Args>...>
(
std::forward
<Args>
(args)...)
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
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...)
bind-partial
is std::bind_front
bind-partial
is std::bind_front
bind-partial
is std::bind_back
bind-partial
is std::bind_back
where
-
Ns
is an integer pack0, 1, ..., (sizeof...(Args) - 1)
,-
g
is an lvalue in the std::invoke expression if it is an lvalue in the call expression, and is an rvalue otherwise. Thus std::move(g)(call_args...) can move the bound arguments into the call, where g(call_args...)
The program is ill-formed if g
has volatile-qualified type.
The member operator() is noexcept if the std::invoke
Exceptions
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_wrapper
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
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
(2,4) (that accept the callable object as an argument for non-type template parameter
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_bind_front |
201907L |
(C++20) | std::bind_front , (1)
|
202306L |
(C++26) | Allow passing callable objects as non-type template arguments to std::bind_front , (2)
|
|
__cpp_lib_bind_back |
202202L |
(C++23) | std::bind_back , (3)
|
202306L |
(C++26) | Allow passing callable objects as non-type template arguments to std::bind_back , (4)
|
Possible implementation
(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> or 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 { /* is the same as above */ } template<auto ConstFn, class... Args> constexpr auto bind_back(Args&&... args) { using F = decltype(ConstFn); if constexpr (std::is_pointer_v<F> or 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)...); }; } |
Example
#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:2024):
- 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
(C++11)
|
binds one or more arguments to a function object (function template) |
(C++11)
|
creates a function object out of a pointer to a member (function template) |