es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Código de plantilla para tipos no polimórficos utilizando lambdas en C++14 o C++17.

Tengo devoluciones de llamada utilizando una lambda que estoy tratando de convertir en una plantilla. El problema es que la clase base del evento no es polimórfica a las clases derivadas. Por favor, vea el código a continuación.

Lo que quiero hacer es tener algún tipo de código de plantilla para la devolución de llamada para no tener que escribir múltiples copias del mismo código.

  auto my_lambda = [](std::shared_ptr<EventBase> event)
  {
    if (std::is_same<T, TypeA>::value) {
      if (event->EventType() != TypeA::EventID()) {
        return;
      }
    } else if(std::is_same<T, TypeB>::value) {
      if (event->EventType() != TypeB::EventID()) {
        return;
      }
    }

    auto event_type =
        std::dynamic_pointer_cast<EventA>(event); //Esto causa un problema al intentar
 convertirlo en una plantilla - ver el código comentado abajo - lo que intenté - esto falla

   // if (std::is_same<T, TypeB>::value)
   // {
   //   event_type =
   //       std::dynamic_pointer_cast<EventB>(event);
   // }

    auto &buffer = event_type->Buffer();
    rval = other_service->Set(T::Buffer, buffer);
    if (rval != OK)
    {
      return;
    }
  };

//Llamando a la lambda aquí para suscribirse al evento
  store_id = some_service->Subscribe(T::EventId, my_lambda);

¡Por favor ayuda!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para convertir la lambda en una plantilla, puedes usar un parámetro de plantilla para el tipo de clase derivada en lugar de usar std::is_same. Esto también solucionaría el problema con la clase base no polimórfica. Aquí tienes un ejemplo de cómo puedes modificar la lambda en una plantilla:

    template<typename eventtype="">
    auto my_lambda = [](std::shared_ptr<eventbase> evento)
    {
      if (evento->EventType() != EventType::EventID()) {
        return;
      }
    
      auto evento_tipo =
          std::dynamic_pointer_cast<eventtype>(evento);
    
      auto &buffer = evento_tipo->Buffer();
      rval = other_service->Set(EventType::Buffer, buffer);
      if (rval != OK)
      {
        return;
      }
    };
    
    // Llamando a la lambda aquí para suscribirse al evento
    store_id = some_service->Subscribe(T::EventId, my_lambda<tipoa>);
    store_id = some_service->Subscribe(T::EventId, my_lambda<tipob>);
    

    Como puedes ver, la lambda ahora es una plantilla que toma un parámetro de tipo EventType que representa el tipo de clase derivada. Luego puedes especializar la lambda para la clase derivada adecuada pasando el tipo como un argumento de plantilla al suscribirte al evento. De esta manera, no necesitas escribir múltiples copias del mismo código y puedes reutilizar la misma lambda de plantilla para diferentes tipos.

Comments are closed.