features descargar compiler c++ c++11

descargar - ¿Inicialización no válida de referencia no constante con subproceso C++ 11?



c++17 descargar (2)

Ajuste x en std::ref cuando cree el hilo.

Si cada vez que creara un std::thread tomaba todas las variables por referencia, piense qué pasaría: si pasara una variable local de stack, sería una referencia pendiente, y se produciría un comportamiento indefinido si el thread sobreviviera al alcance de esa variable de almacenamiento automático. Esto sucedería mucho en la práctica, y daría lugar a muchos errores. En su lugar, std::thread por defecto toma (califica a través del reenvío perfecto) todos los argumentos (incluidas las variables) por valor.

El std::future podría funcionar silenciosamente al llamar a su función de trabajador al pasar una copia de lvalue local de subproceso de x , pero eso sería bastante confuso: la tarea de trabajador editaría x que usted pensó que pasó por referencia, y no lo haría t aparece en la x fuera de la tarea. En su lugar, le da útil ese mensaje de error. ¡Deberías agradecer a tus afortunadas estrellas por ello!

Para indicar que realmente desea no tomar algo por valor, envuélvalo en std::ref , y ahora se pasa a la función de trabajo como referencia. En este caso, usted es responsable de administrar el tiempo de vida de la referencia para que la información a la que se hace referencia dure al menos mientras la tarea del trabajador de std::future la necesite.

Estoy recibiendo un error sobre

error: inicialización no válida de referencia no constante de tipo ''int &'' a partir de un valor de tipo ''int''

desde

#include <thread> #include <iostream> using namespace std; void func(int& i){ cout<<++i<<endl; } int main(){ int x=7; thread t(func,x); t.join(); return 0; }

Entiendo que no puedo hacer thread(func, 4) pero x es una variable, no una temporal.

Estoy usando gcc 4.7 con -std = c ++ 11 -pthread

¿Por qué está ocurriendo este error?


La especificación para el constructor std::thread dice

Efectos: construye un objeto de tipo hilo. El nuevo hilo de ejecución ejecuta INVOKE ( DECAY_COPY ( std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) con las llamadas a DECAY_COPY evaluadas en el hilo de construcción. .

Donde DECAY_COPY (x) significa llamar a decay_copy(x) donde se define como:

template <class T> typename decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); }

Lo que esto significa es que los argumentos "decaen" y se copian, lo que significa que se reenvían por valor y pierden cualquier calificación cv. Debido a que la función de destino ejecutada por el hilo quiere tomar su parámetro por referencia , se obtiene un error del compilador que indica que la referencia no puede vincularse a un objeto pasado por valor.

Esto es por diseño, de modo que, de forma predeterminada, las variables locales pasadas a un std::thread se pasan por valor (es decir, se copian) no por referencia, de modo que el nuevo thread no tenga referencias pendientes a variables locales que queden fuera del alcance, lo que lleva a al comportamiento indefinido.

Si sabe que es seguro pasar las variables por referencia, entonces debe hacerlo explícitamente, utilizando un reference_wrapper que no se verá afectado por la semántica de "decaimiento" y reenviará la variable por referencia al objeto objetivo. Puedes crear un reference_wrapper usando std::ref .