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.

Función run de QThread con número desconocido de argumentos y tipos.

Estoy tratando de escribir una función QThread. Y en la función run hay una función m_pFunc en el bucle while. La m_pFunc es un puntero a función con un número desconocido de argumentos y tipos. ¿Cómo puedo lograr este puntero a función?

cpp
void func1(int){ cout<<"func1"<<endl; }="" void="" func2(int,char){=""></endl;><endl; }="" class="" cthread:="" public="" qthread="" {="" q_object="" q_disable_copy(cthread)="" public:="" using="" pfunc="void" (*)(...);="" ¿cómo="" lograrlo?="" cthread()="default;" ~cthread()="default;" cthread(const="" pfunc="" pfunc)="" :="" m_brunning(false),="" m_pfunc(pfunc){="" };="" protected:="" void="" run()="" {="" m_brunning="true;" while="" (m_brunning)="" {="" m_pfunc(...);//="" ¿cómo="" ejecutar="" este="" puntero="" a="" función?="" }="" }="" private:="" std::atomic_bool="" m_brunning;="" pfunc="" m_pfunc;="" };="" cthread="" ct1(func1);="" cthread="" ct2(func2);="" ct1.run();="" ct1.run();=""
=”” resultado=”” esperado:=”” “`=””> func1

func2
“`</endl;>

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para lograr un puntero a una función con un número desconocido de argumentos y tipos (PFunc), puedes usar una plantilla variadic. Aquí hay una implementación de ejemplo:

    “`c++
    class CThread : public QThread {
    Q_OBJECT
    Q_DISABLE_COPY(CThread)

    public:
    template
    CThread(Func&& func)
    : m_bRunning(false)
    , m_pFunc(std::forward(func))
    {}

    protected:
    void run() override {
    m_bRunning = true;
    while (m_bRunning) {
    std::apply(m_pFunc, m_args); // llamar a la función con los argumentos almacenados
    }
    }

    public:
    template<typename… args=””>
    void call(Args&&… args) {
    m_args = std::make_tuple(std::forward(args)…); // almacenar los argumentos para su uso posterior
    }

    private:
    std::atomic_bool m_bRunning;
    std::function<void(args…)> m_pFunc;
    std::tuple<args…> m_args; // almacenar los argumentos para su uso posterior
    };


    Explicación: - La plantilla de clase `CThread` toma un objeto invocable (por ejemplo, un puntero a una función, un lambda o un functor) como parámetro. El tipo del objeto invocable se deduce mediante una referencia reenviada (`Func&&`) y se almacena como un miembro `std::function` llamado `m_pFunc`. - La función miembro `void call(Args&&... args)` toma los argumentos para la función que se llamará y los almacena en el miembro de tipo tuple `m_args`. - En la función `run`, la función almacenada `m_pFunc` se llama con `std::apply`, lo que permite llamar a una función con una tupla de argumentos. - Ten en cuenta que la firma de la función se fija en tiempo de compilación, por lo que no puedes llamar a una función con argumentos diferentes a los almacenados en `m_args`. Uso: ```c++ void func1(int){ std::cout << "func1" << std::endl; } void func2(int,char){ std::cout << "func2" << std::endl; } CThread ct1(func1); CThread ct2(func2); ct1.call(42); // hacer que ct1 ejecute func1 con el argumento 42 ct2.call(42, 'a'); // hacer que ct2 ejecute func2 con los argumentos 42 y 'a' ct1.start(); ct2.start(); ct1.wait(); ct2.wait();

    Salida:

    func1
    func2
    </args…></void(args…)></typename…>

Comments are closed.