std::bind_front, std::bind_back
| Definido en el archivo de encabezado <functional>
|
||
template <class F, class... Args> constexpr /*no especificado*/ bind_front( F&& f, Args&&... args ); |
(1) | (desde C++20) |
template <class F, class... Args> constexpr /*no especificado*/ bind_back( F&& f, Args&&... args ); |
(2) | (desde C++23) |
Las plantillas de función bind_front y bind_back generan un envoltorio de llamada de reenvío para f. Llamar a este envoltorio es equivalente a invocar f con sus parámetros sizeof...(Args) (1) first o (2) last vinculados a args.
En otras palabras:
std::bind_front(f, bound_args...)(call_args...)es equivalente astd::invoke(f, bound_args..., call_args...).std::bind_back(f, bound_args...)(call_args...)es equivalente astd::invoke(f, call_args..., bound_args...).
El programa está mal formado si cualquiera de los siguientes es false:
std::is_constructible_v<std::decay_t<F>, F>std::is_move_constructible_v<std::decay_t<F>>(std::is_constructible_v<std::decay_t<Args>, Args> && ...)(std::is_move_constructible_v<std::decay_t<Args>> && ...)
Parámetros
| f | - | Objeto invocable que cumple con los requerimientos de Callable (objeto función, puntero a función, referencia a función, puntero a función miembro o puntero a dato miembro) que estará vinculado a algunos argumentos. |
| args | - | Lista de los argumentos a vincular a los parámetros sizeof...(Args) (1) first o (2) last de f.
|
| Requisitos de tipo | ||
- debe satisfacer los requisitos de MoveConstructible.
| ||
Valor de retorno
Un objeto función de tipo T que no está especificado, excepto que los tipos de objetos devueltos por dos llamadas a std::bind_front o std::bind_back con los mismos argumentos son los mismos.
El objeto devuelto (el envoltorio de llamada) tiene las siguientes propiedades:
vinculación-parcial tipo de retorno
Sea vinculación-parcial std::bind_front o std::bind_back.
Objetos miembro
El objeto devuelto se comporta como si tuviera un objeto miembro fd de tipo std::decay_t<F> inicializado directamente sin usar la inicialiación de lista a partir de std::forward< F>(f), y un objeto std::tuple tup construido con std::tuple<std::decay_t<Args>...> (std::forward<Args>(args)...), excepto que el comportamiento de asignación del objeto devuelto no está especificado y los nombres son solo para exposición.
Constructores
El tipo de retorno de vinculación-parcial se comporta como si sus constructores de copia o movimiento realizaran una copia o movimiento miembro por miembro. Es tipo es CopyConstructible si todos sus objetos miembro (especificados arriba) son CopyConstructible, y MoveConstructible de lo contrario.
Función miembro operator()
Dado un objeto G obtenido de una llamada anterior a vinculación-parcial(f, args...), cuando un gl-valor g que designa a G se invoca en una expresión de llamada a función g(call_args...), toma lugar una invocación del objeto almacenado, como si fuera por
std::invoke(g.fd, std::get<Ns>(g.tup)..., call_args...), cuandovinculación-parcialesstd::bind_front, o porstd::invoke(g.fd, call_args..., std::get<Ns>(g.tup)...), cuandovinculación-parcialesstd::bind_back, donde
Nses un paquete de enteros0, 1, ..., (sizeof...(Args) - 1)ges un l-valor en la expresión std::invoke si es un l-valor en la expresión de llamada, y es un r-valor de lo contrario. Por lo tanto,std::move(g)(call_args...)puede mover los argumentos vinculados a la llamada, dondeg(call_args...)los copiaría.
El programa está mal formado si g tiene un tipo calificado como volatile.
El miembro operator() es noexcept si la expresión std::invoke a la que llama es noexcept (en otras palabras, conserva la especificación de excepción del operador de llamada a función subyacente).
Excepciones
Solo lanza una excepción si la construcción del objeto función almacenado lanza o cualquiera de los argumentos vinculados lanza.
Notas
Estas plantillas de función están destinadas a reemplazar std::bind. A diferencia de std::bind, no admiten la reorganización arbitraria de argumentos y no tienen un tratamiento especial para expresiones de vinculación anidadas o std::reference_wrapper. Por otro lado, prestan atención a la categoría de valor del objeto envoltorio de llamada y propagan la especificación de excepción del operador de llamada a función subyacente.
Como se describe en std::invoke, al invocar un puntero a función miembro no estática o un puntero a dato miembro no estático, el primer argumento debe ser una referencia o puntero (incluido, posiblemente, un puntero inteligente como std::shared_ptr y std::unique_ptr) a un objeto a cuyo miembro se accederá.
Los argumentos para std::bind_front o std::bind_back se copian o mueven, y nunca se pasan por referencia a menos que estén envueltos en std::ref o std::cref.
| Macro de prueba de característica | Valor | Estándar |
|---|---|---|
__cpp_lib_bind_front |
201907L |
(C++20) |
__cpp_lib_bind_back |
202202L |
(C++23) |
Ejemplo
#include <functional>
#include <iostream>
int menos(int a, int b)
{
return a - b;
}
struct S
{
int val;
int menos(int arg) const noexcept { return val - arg; }
};
int main()
{
auto cincuenta_menos = std::bind_front(menos, 50);
std::cout << cincuenta_menos (3) << '\n'; // equivalente a `menos(50, 3)`
auto miembro_menos = std::bind_front(&S::menos, S{50});
std::cout << miembro_menos (3) << '\n'; // equivalente a `S tmp{50}; tmp.menos(3)`
// se conserva la especificación noexcept
static_assert(! noexcept(cincuenta_menos (3)));
static_assert(noexcept(miembro_menos (3)));
// vincular a una lambda
auto mas = [](int a, int b) { return a + b; };
auto cuarenta_mas = std::bind_front(mas, 40);
std::cout << cuarenta_mas(7) << '\n'; // equivalente a `mas(40, 7)`
#ifdef __cpp_lib_bind_back
auto mult_y_sumar = [](int a, int b, int c) { return a * b + c; };
auto mult_mas_siete = std::bind_back(mult_y_sumar, 7);
std::cout << mult_mas_siete(4, 10) << '\n'; // equivalente a `mult_y_sumar(4, 10, 7)`
#endif
}
Posible salida:
47
47
47
47
Véase también
(C++11) |
Vincula uno o más argumentos a un objeto función. (plantilla de función) |
(C++11) |
Crea un objeto función de un puntero a un miembro. (plantilla de función) |