2011-11-11 14 views
14

Duplicar posible:
Bind Vs Lambda?¿std :: bind sigue siendo útil en comparación con lambdas?

Mi uso de std::bind había caído a 0 ahora que lambdas han ganado un amplio apoyo.

¿Hay algún problema que std::bind sea especialmente adecuado para una función lambda?

¿Hubo una razón de peso para mantener std::bind en el estándar una vez que se agregaron lambdas?

+3

La vinculación aún puede ser __far__ más sucinta que lambdas si los tipos de argumento son largos. – ildjarn

+1

http://stackoverflow.com/questions/1930903/bind-vs-lambda/4581747#4581747 –

+1

Todavía son bastante ortogonales IMO. –

Respuesta

21

Puede capturar por valor o por referencia, y el problema es que la captura de valor realmente significa 'captura por parte dupdo'. Este es un show stopper para un tipo de solo movimiento. Así no se puede utilizar un lambda de hacer lo siguiente:

struct foo { void bar() {} }; 

std::unique_ptr<foo> f { new foo }; 
auto bound = std::bind(&foo::bar, std::move(f)); 
static_assert(std::is_move_constructible<decltype(bound)>::value, ""); 
bound(); 

IIRC brevemente el Comité de Normas consideró que permite la expresión arbitraria dentro de una lista de captura de lambda para resolver este (que podría parecerse a [std::move(f)] { return f.bar(); }), pero no lo hago Creo que hubo una propuesta sólida y C++ 11 ya se estaba retrasando.

Eso y la restricción del comportamiento monomórfico con lambdas son los factores decisivos para mí.

+1

Buen ejemplo! ¿El objeto 'bind' termina siendo dueño del objeto' foo' dinámico? ¿Se convierte en sí mismo no copiable? –

+0

@KerrekSB Absolutamente, en ambas cuentas. –

+0

@Luc gran ejemplo, estaba buscando exactamente esto. Mi problema restante es que esa expresión de vinculación no se puede asignar a std :: function . Sin embargo, puede sin el unique_ptr y el movimiento. ¿Hay alguna manera de pasar ese enlace como devolución de llamada a otra función? (La intención es que la devolución de llamada sea propietaria del objeto y lo elimine una vez que se destruya la devolución de llamada). –

4

bind es ideal para crear referencias a cota función miembro:

Foo x; 
auto f = std::bind(&Foo::bar, &x, 12, true); 
register_callback(f); 

Editar: Como Luc Danton demuestra, esta construcción es muy flexible y permite el puntero ejemplo entre en una sorprendente variedad de formas (por ejemplo, punteros inteligentes). [/]

Si es factible, una lambda es probablemente preferible, especialmente porque ofrece un mayor potencial para la optimización, pero las expresiones de enlace todavía tienen su lugar.

(En cualquier caso, auto es preferible sobre std::function para el tipo para almacenar el objeto invocable.)

+2

bind es genial pero lambdas es mejor. Este 'auto f = [& x]() {devuelve x.bar (12, verdadero); }; 'es bastante breve. Entonces, de nuevo, ¿cuándo se preferiría 'std :: bind'? –

+0

@deft_code: Hmm ... 'bind 'rellena los marcadores de posición al final (mi' f' todavía podría tomar muchos argumentos), así que quizás eso sea más claro cuando la expresión de enlace sea parte de una plantilla en alguna parte. ¡Pero es una buena pregunta! –

Cuestiones relacionadas