std::bind_front, std::bind_back
Defined in header <functional>
|
||
template< class F, class... Args > constexpr /* unspecified */ bind_front( F&& f, Args&&... args ); |
(1) | (since C++20) |
template< auto f, class... Args > constexpr /* unspecified */ bind_front( Args&&... ); |
(2) | (since C++26) |
template< class F, class... Args > constexpr /* unspecified */ bind_back( F&& f, Args&&... args ); |
(3) | (since C++23) |
template< auto f, class... Args > constexpr /* unspecified */ bind_back( Args&&... ); |
(4) | (since C++26) |
Function templates std::bind_front
and std::bind_back
generate a forwarding call wrapper for f. Calling this wrapper is equivalent to invoking f with its first (for overloads (1,2)) or last (for overloads (3,4)) sizeof...(Args) parameters bound to args.
The following expressions are equivalent:
Let F
be the type of f. The program is ill-formed if any of the following conditions is false:
This section is incomplete Reason: Reflect C++26's enhancements (2,4) from "P2714R1 - Bind front and back to NTTP callables" |
Contents |
[edit] Parameters
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 first (1,2) or last (3,4) sizeof...(Args) parameters of f
|
Type requirements | ||
-std::decay_t<F> must meet the requirements of MoveConstructible. (1,3)
| ||
-std::decay_t<Args>... must meet the requirements of MoveConstructible. (1-4)
|
[edit] Return value
A function object 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.
The returned object (call wrapper) has the following properties:
bind-partial return type
Let bind-partial
be either std::bind_front
or std::bind_back
.
Member objects
The returned object behaves as if it holds a member object fd
of type std::decay_t<F> direct-non-list-initialized from std::forward<F>(f), and an std::tuple object tup
constructed with std::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 bind-partial(f, 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...), when
bind-partial
isstd::bind_front
, or by - std::invoke(g.fd, call_args..., std::get<Ns>(g.tup)...), when
bind-partial
isstd::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...) 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).
[edit] Exceptions
May throw any exception thrown by calling the constructor of:
[edit] 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.
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)
|
[edit] Example
#include <cassert> #include <functional> #include <iostream> 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); std::cout << fifty_minus(3) << ' '; // equivalent to minus(50, 3) auto member_minus = std::bind_front(&S::minus, S{50}); std::cout << member_minus(3) << ' '; // equivalent to: S tmp{50}; tmp.minus(3) // 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); std::cout << forty_plus(7) << ' '; // equivalent to plus(40, 7) #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<decltype(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); std::cout << mul_plus_seven(4, 10) << ' '; // equivalent to madd(4, 10, 7) #endif #if __cpp_lib_bind_back >= 202306L auto mul_plus_seven_cpp26 = std::bind_back<decltype(madd)>(7); assert(mul_plus_seven_cpp26(4, 10) == 47); #endif std::cout << '\n'; }
Possible output:
47 47 47 47
[edit] References
- C++26 standard (ISO/IEC 14882:2026):
- 22.10.14 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]
[edit] 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) |