1. ¿x(123)
realmente llama al operator()
generado que funcionó std::function
que a su vez llama al operator()
del functor que std::bind
generó que finalmente llama a func
? ¿Esto se optimiza en algo tan óptimo como llamar al func(123)
?
Si tiene habilitadas las optimizaciones, el 'material' se inserta y puede contar con que es tan óptimo como llamar al func(123)
.
2. ¿Dónde se genera el functor que genera std::bind
? ¿En qué alcance? ¿Y cómo lo llama std::bind
? (Puede haber colisiones de nombres)
precisando: bind
genera una 'fugaz', definido por la implementación, se unen a la expresión, que es asignable a function<>
. La función es solo una plantilla de clase (Gracias, Luc T.). Y vive en la biblioteca estándar. Sin embargo, las expresiones de enlace están definidas por la implementación.
La biblioteca estándar tiene vienen con rasgos (std::is_bind_expression<>
) para permitir la detección MPL de tales expresiones. Una característica decisiva de las expresiones bind sobre std :: function es que son (como yo llamaría) objetos callificables diferidos (es decir, que conservan la semántica completa del sitio de llamadas, incluida la capacidad de seleccionar sobrecargas en el sitio de la aplicación real). std::function<>
, por otro lado, se compromete con un único prototipo y almacena internamente el callable object por borrado de tipo (piensa variant
o any
).
3. ¿Pueden las lambdas reemplazar todos los usos de std :: bind?
4. ¿Es std :: bind tan óptimo como implementarlo como un lambda?
AFAICT lambdas debería compilarse hasta casi lo mismo que las expresiones de vinculación. Una cosa que yo creo lambda no pueden hacer que las expresiones se unen puede es nested bind expressions
Editar Mientras que el lenguaje específico de las expresiones unen anidadas no se replicable usando lambdas, lambdas son, por supuesto, capaz de expresar (casi) la misma mucho más natural:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5. ¿Qué pasa con la sintaxis del argumento de plantilla de std::function
? ¿Cómo se analiza y cómo puedo usar esa sintaxis de argumento de la plantilla en otro lugar?
Es sólo una firma de función (la tipo de una función), que se pasa como parámetro de plantilla.
También puede usarlo como un tipo de parámetro de función, que degrada a un puntero de función (similar a cómo los parámetros de valor de matriz se degradan a los indicadores, ¡Gracias David!). En la práctica, la mayoría en cualquier lugar, siempre y cuando usted no tiene una necesidad de nombre de una variable/Tipo:
void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax
void sample(int, double) { }
int main()
{
receiveFunction(sample);
}
void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
// void (f)(int, double) // ... also ok
{
// ..
}
Para 2. usted podría estar interesado en http://www.artima.com/cppsource/type_erasure.html – Flexo
Una pregunta a la vez, por favor. Cada publicación SO es una pregunta. –
Esto es más un conjunto de preguntas que una pregunta concreta, y van desde la sintaxis (para el argumento de 'function <>') al comportamiento (¿dónde se produce el resultado de bind live? ¿Puede lambda sustituirlas?) El rendimiento (¿Está optimizado?) –