std::function
es un objeto de borrado de tipo. Eso significa que borra los detalles de cómo ocurren algunas operaciones y les proporciona una interfaz de tiempo de ejecución uniforme. Para std::function
, el primario1 Las operaciones son copia/movimiento, destrucción y 'invocación' con operator()
- El "operador de llamadas de función".
En inglés menos abstruso, significa que std::function
Puede contener casi cualquier objeto que actúe como un puntero de función en cómo lo llama.
La firma que admite va dentro de los soportes de ángulo: std::function<void()>
Toma cero argumentos y no devuelve nada. std::function< double( int, int ) >
toma dos int
Argumentos y devoluciones double
. En general, std::function
Admite almacenar cualquier objeto similar a la función cuyos argumentos se pueden convertir de su lista de argumentos y cuyo valor de retorno se puede convertir en su valor de retorno.
Es importante saber que std::function
y los lambdas son bestias diferentes, aunque compatibles.
La siguiente parte de la línea es una lambda. Esta es una nueva sintaxis en C ++ 11 para agregar la capacidad de escribir objetos simples similares a la función: objetos que se pueden invocar con ()
. Dichos objetos se pueden borrar y almacenar en un std::function
A costa de alguna parte de tiempo de ejecución.
[](){ code }
En particular es una lambda realmente simple. Corresponde a esto:
struct some_anonymous_type {
some_anonymous_type() {}
void operator()const{
code
}
};
Una instancia del tipo de pseudofunción simple anterior. La clase real como la anterior es "inventada" por el compilador, con un nombre único definido por implementación (a menudo incluyendo símbolos que ningún tipo definido por el usuario puede contener) (no sé si es posible que pueda seguir el estándar sin inventar Tal clase, pero cada compilador que conozco realmente crea la clase).
La sintaxis Lambda completa se ve como:
[ capture_list ]( argument_list )
-> return_type optional_mutable
{
code
}
Pero muchas partes se pueden omitir o dejar vacías. Capture_List corresponde tanto al constructor del tipo anónimo resultante como a sus variables miembros, el argumento_list los argumentos del operator()
, y el tipo de retorno el tipo de retorno. El constructor de la instancia de Lambda también se llama mágicamente cuando la instancia se crea con Capture_List.
[ capture_list ]( argument_list ) -> return_type { code }
Básicamente se convierte en
struct some_anonymous_type {
// capture_list turned into member variables
some_anonymous_type( /* capture_list turned into arguments */ ):
/* member variables initialized */
{}
return_type operator()( argument_list ) const {
code
}
};
Tenga en cuenta que en C ++ 20 Se agregaron argumentos de plantilla a Lambdas, y eso no está cubierto anteriormente.
[]<typename T>( std::vector<T> const& v ) { return v.size(); }
1 Además, se almacena RTTI (TypeId), y se incluye la operación de tipo de devolución de retorno de origen.