Tengo un lambda dentro de un bucle for con el parámetro variable de bucle en el lambda. Cuando lo ejecuto, espero que salgan los números 0-9. Pero como es una lambda, la x no se evalúa inmediatamente.Lambda dentro del bucle
for(int x = 0; x < n; ++x)
{
vec.push_back(thread{[&x](){
m.lock();
cout << x << endl;
m.unlock();
}});
}
Salida:
0
3
3
9
etc.
La solución para otros idiomas sería la creación de una variable temporal,
for(int x = 0; x < n; ++x)
{
int tmp = x;
vec.push_back(thread{[&tmp](){
m.lock();
cout << tmp << endl;
m.unlock();
}});
}
pero eso no parece funcionar .
ver Threads receiving wrong parameters
Bono:
En mi búsqueda de una respuesta, me encontré con este problema Generalizing C++11 Threads class to work with lambda que no recomienda el uso de un recipiente que pueda invalidar los iteradores. ¿Por qué sería/
Me siento un poco tonto. No entendí para qué era el & en las expresiones lambda. Para este ejemplo simplificado, sí, un lock_guard sería apropiado. Pero en la aplicación real, la función hace mucho que no necesita ser bloqueada. En ese caso, un mutex sería apropiado para bloquear y desbloquear solo alrededor de la parte importante, ¿correcto? – SaulBack
@SaulBack: No. Deberías usar 'lock_guard' de cualquier forma. Si solo quiere bloquear cierto código, use un bloque explícito con '{}' para encerrar el código bloqueado. Esta es la codificación RAII básica aquí. –
@SaulBack: especialmente en el código complicado que desea utilizar RAII, por ejemplo, 'std :: lock_guard'! En este ** ejemplo ** trivial puedo ver que no es necesario, pero en el momento en que es un poco más complejo las cosas se ponen rápidamente fuera de control. Si necesita restringir el alcance donde se guarda el bloqueo, use un alcance, es decir, un par de llaves: '{}'. –