elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Uso de Threads y error de compilación asignado a una libreria estandar...
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Uso de Threads y error de compilación asignado a una libreria estandar...  (Leído 1,518 veces)
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Uso de Threads y error de compilación asignado a una libreria estandar...
« en: 4 Agosto 2019, 00:58 am »

Buenas..

Tengo este código y me está saliendo error, ppienso que la sintaxis está correcta.. aun no entiendo por qué el error..  Alguna pista?


Ver en el siguiente enlace el codigo para probar:
https://onlinegdb.com/ryO2ptQ7B

Saludos.


Edit : Le quite el simbolo de referencia en el parámetro para la funcion de la linea 5 y ahí compiló..
Pero no veo por qué...


« Última modificación: 4 Agosto 2019, 06:37 am por digimikeh » En línea

Dungeons & dragons;
dragons.Attack();
Loretz

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Uso de Threads y error de compilación asignado a una libreria estandar...
« Respuesta #1 en: 4 Agosto 2019, 21:17 pm »

...
Citar
Le quite el simbolo de referencia en el parámetro para la funcion de la linea 5 y ahí compiló..
Pero no veo por qué...

Para poner las cosas más a mano, quitando de tu ejemplo lo que no viene al caso:
Código
  1. #include <iostream>
  2. #include <thread>
  3. #include <vector>
  4.  
  5. void f(std::vector<double>& vd) {
  6.    for (auto& v : vd)
  7.        std::cout << "From f -> " << v << std::endl;
  8. }
  9.  
  10. int main() {
  11.    std::vector<double> vd{ 2.5, 5.5, 7.1 };
  12.  
  13.    std::thread t0{ f, vd };      //<-- Error : No type named type in clas std::result_of))(std::vector&)> Si comento esta linea compila...
  14.  
  15.    t0.join();
  16.  
  17.    return 0;
  18. }
  19.  

Y dices que si quitas la referencia, si la función "f" toma su argumento por valor, entonces compila sin error. Está bien, y quisieras saber por qué...

Porque el constructor de thread que estás invocando es:
Código:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
Ver: https://en.cppreference.com/w/cpp/thread/thread/thread

Y en ese caso, en las NOTAS, se aclara que
Citar
"The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref). "

NO es que lo esté aclarando, sólo se dice que "Así debe ser",

Entonces, en tu ejemplo, podrías poner:

Código
  1. std::thread t0{ f, std::ref(vd) };

Funciona así porque std::ref devuelve ese wrapper que necesitas en el segundo argumento template, que se pasa por valor, pero se comporta como una referencia (encapsula, contiene, envuelve una referencia). https://en.cppreference.com/w/cpp/utility/functional/ref


Pero preguntabas "por qué".

Bueno, porque al construir la instancia de thread, en su constructor se invoca a la función del primer parámentro, con los parámetros del segundo parámetro, ¿de acuerdo?, pero esa llamada a f se hace a través de
Código
  1. std::invoke(decay_copy(std::forward<Function>(f)),
  2.            decay_copy(std::forward<Args>(args))...);

Donde se invoca la función f con el "parameter pack" que devuelva "decay_copy", ¿verdad?

Pero esa "decay_copy" sólo hace un "forward" del pack que recibe, y devuelve a su vez un std::decay_t.

Y, ajá, acá está, es eso. Si te fijas en la documentación sobre std::dacay_t: https://en.cppreference.com/w/cpp/types/decay verás que para este caso:

Citar
    the member typedef type is std::remove_cv<std::remove_reference<T>::type>::type.
These conversions model the type conversion applied to all function arguments when passed by value.

Ahorá sí, no sólo está aplicando std::remove_cv, que no tiene que ver con lo nuestro en este momento, sino que, fundamentalmente, aplica std::remove_reference al T::type que recibe como parámetro, que eso sí termina de explicar por qué necesitamos un wrapper cuando la función que se va a ejecutar en el nuevo thread toma sus parámetros por referencia.





Quise editar mi respuesta anterior y quedó una completa basura, así que escribo aquí a modo de apéndice:

Otra variante para considerar es que el parámetro de f sea una const reference:
Código:
void f(const std::vector<double>& vd)

o, como hay quien prefiere:
Código:
void f(std::vector<double> const& vd)
(con el "const" antes de &)


« Última modificación: 5 Agosto 2019, 09:52 am por Eternal Idol » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Error tonto con threads y sockets « 1 2 3 »
Java
Debci 22 11,616 Último mensaje 28 Diciembre 2009, 10:20 am
por Debci
Problema con Threads en libreria SDL en C++
Programación C/C++
Guillermo575 9 7,123 Último mensaje 7 Abril 2011, 06:04 am
por Guillermo575
duda con libreria estandar
Programación C/C++
Samael.Black 1 1,810 Último mensaje 26 Abril 2011, 23:10 pm
por leogtz
John the ripper Error de compilacion -- make: *** [generic.h] Error 1 --
GNU/Linux
hbenzin 2 3,909 Último mensaje 20 Agosto 2011, 23:42 pm
por hbenzin
Error de compilacion con GCC, libreria iostream « 1 2 »
Programación C/C++
eternoneofito 16 23,729 Último mensaje 23 Agosto 2011, 00:20 am
por rir3760
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines