valor referencia que por pasar parametros parametro objetos entrada como clase c++ stdbind

c++ - que - std:: bind pierde la referencia cuando se entrega como referencia rvalue



ref c# (2)

std::bind() está diseñado para semántica de valor ( como R. Martinho Fernandes explica muy bien en su respuesta ), y crea copias internamente. Lo que necesitas / quieres es std::ref :

callback(std::bind(test, std::ref(t))); // ^^^^^^^^^^^

std::ref devuelve un objeto std::reference_wrapper<> que envuelve una referencia a su argumento original. De esta manera, el objeto reference_wrapper alrededor de t se copia, y no t sí mismo.

Esto le permite elegir entre semántica de valor (asumida por defecto) y semántica de referencia (que requiere su intervención explícita).

Aquí hay un ejemplo en vivo .

Tengo el siguiente código:

#include <stdio.h> #include <functional> template <typename T> auto callback(T&& func) ->decltype(func()) { return func(); } double test(double& value) { value=value+1.0; return value; } int main(void) { double t=1.0; printf("%f/n",t); test(t); printf("%f/n",t); callback(std::bind(test,t)); printf("%f/n",t); }

Y da salida

1.000000 2.000000 2.000000

Lo que implica que la función de callback obtuvo una copia de t lugar de una referencia a t . Me pregunto qué sucedió, ya que para std::bind debería ser un reenvío perfecto.


std::bind usa valores semánticos por defecto. Es un predeterminado sano que le permite hacer cosas como las siguientes de forma segura.

int f(double x); auto fun = std::bind(f, 1.0); // stores a copy, not a reference to a temporary fun();

El uso de la semántica de valores es seguro: el tiempo de vida de los argumentos enlazados se convierte en el tiempo de vida del objeto devuelto por bind. Usar la semántica de referencia no tendría esa garantía. Por lo tanto, debe ser explícito cuando desee semántica de referencia; Si te metes en problemas, entonces es tu culpa. Para hacer eso necesitas usar std::ref :

int main(void) { double t=1.0; printf("%f/n",t); test(t); printf("%f/n",t); callback(std::bind(test, std::ref(t))); printf("%f/n",t); }

Este mismo protocolo se usa en otras partes de la biblioteca estándar, como el constructor std::thread .