Siguiendo this excellent tutorial para futuros , promesas y tareas envasados llegué al punto donde quería preparar mi propia tarea¿Cómo creo una packaged_task con parámetros?
#include <iostream>
#include <future>
using namespace std;
int ackermann(int m, int n) { // might take a while
if(m==0) return n+1;
if(n==0) return ackermann(m-1,1);
return ackermann(m-1, ackermann(m, n-1));
}
int main() {
packaged_task<int(int,int)> task1 { &ackermann, 3, 11 }; // <- error
auto f1 = task1.get_future();
thread th1 { move(task1) }; // call
cout << " ack(3,11):" << f1.get() << endl;
th1.join();
}
Por lo que yo puedo descifrar el gcc-4.7.0 mensaje de error espera los argumentos de manera diferente? ¿Pero cómo? Trato de acortar el mensaje de error:
error: no matching function for call to
'std::packaged_task<int(int, int)>::packaged_task(<brace-enclosed initializer list>)'
note: candidates are:
std::packaged_task<_Res(_ArgTypes ...)>::---<_Res(_ArgTypes ...)>&&) ---
note: candidate expects 1 argument, 3 provided
...
note: cannot convert 'ackermann'
(type 'int (*)(int, int)') to type 'std::allocator_arg_t'
¿Es mi variante de la forma que proporcione los parámetros para ackermann
mal? ¿O es el parámetro de plantilla incorrecto? No doy los parámetros 3,11
a la creación de hilo, ¿verdad?
Actualizar otras variantes sin éxito:
packaged_task<int()> task1 ([]{return ackermann(3,11);});
thread th1 { move(task1) };
packaged_task<int()> task1 (bind(&ackermann,3,11));
thread th1 { move(task1) };
packaged_task<int(int,int)> task1 (&ackermann);
thread th1 { move(task1), 3,11 };
hmm ... ¿soy yo, o es el beta-gcc?
En cuanto a los requisitos para 'std :: bind', no es cierto que se requiera que los argumentos sean copiables. El párrafo es demasiado largo para pegarlo aquí, es 20.8.9.1.2 Enlace de plantilla de función [func.bind.bind] párrafo 5. Los requisitos actuales son que los tipos almacenados se muevan de forma constructiva y construible a partir de los argumentos pasados. Aunque sí recuerdo un envío de implementación defectuoso con GCC que requería CopyConstructible. (Sin embargo, no es el problema que enfrenta el OP.) –
@Luc: tienes razón, lo he olvidado. –
El código funciona, pero tengo una pregunta en la línea 'std :: unique_lock l (td.m);' ¿no es el mutex en el hilo ya bloqueado cuando está comprobando la variable de condición? Creo que me falta algo allí. Pensé que bloquea el mutex en el hilo y luego espera a que la bandera de parada o el trabajo se agregue a la cola. En este caso, ¿el hilo principal no esperaría a que se liberara el bloqueo? ¿Es esto debido a un falso despertar que esto funciona? –
bjackfly