сохранение обратного вызова с параметрами неизвестного типа в объекте

#c

#c

Вопрос:

Я хочу сохранить обратный вызов внутри объекта, который будет вызван после завершения асинхронной операции. Проблема в том, что один из аргументов, который будет передан обратному вызову, не будет известен до завершения асинхронной операции. Вот объект, который будет хранить обратный вызов:

     template<typename ... ResultColumnTypes>
    class PostgresCallerQueryResult : public PostgresCallerResult
    {
    public:
        PostgresCallerQueryResult(std::function<void(bool success, ozo::rows_of<ResultColumnTypes...> amp;results)> callback):
        m_results(std::make_shared<ozo::rows_of<ResultColumnTypes...>>()),
        m_callback(callback)
        {}
    ~PostgresCallerQueryResult(){}
    PostgresCallerQueryResult ( const PostgresCallerQueryResult amp; ) = delete;

    bool is_empty()
    {
        if (m_results == nullptr)
        {
            return true;
        }
        
        return (*m_results).empty();
    }
    ozo::rows_of<ResultColumnTypes...>amp; get_data()
    {   
        return (*m_results);
    }
    void callback()
    {
        m_callback(m_success, get_data());
    }
    
private:
    std::shared_ptr<ozo::rows_of<ResultColumnTypes...>> m_results;
    std::function<void(bool success, ozo::rows_of<ResultColumnTypes...> amp;results)> m_callback;
};
 

Таким образом, цель состоит в том, чтобы у «m_callback» был еще 1 параметр, который неизвестен при создании объекта.

Вот как обратный вызов передается объекту:

 int main()
{
   postgres_caller->query(std_func, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
}

template<typename... ResultColumnTypes, typename... ParameterTypes>
void PostgresCaller::query(std::function<void(bool success, ozo::rows_of<ResultColumnTypes...>amp; results)> callback, const std::stringamp; query, ParameterTypesamp;amp; ... parameters)
{
    SVS_TRACE1 << "executing query";

    auto result = std::make_unique<PostgresCallerQueryResult<ResultColumnTypes...>>(callback);
    
    //start the asynchornous query
    ozo::request(m_connection_pool[AsyncEngine::instance()->get_io()],
                 ozo::make_query(query, std::forward<ParameterTypes>(parameters)...),
                 ozo::into(result->get_data()),
                 [m_self = shared_from_this(), result = std::move(result)](ozo::error_code ec, auto connection) mutable
                 {
                    m_self->query_result(std::move(ec), std::move(connection), std::move(result));
                 });        
}
 

Когда асинхронная операция будет завершена, будет вызван query_result с «соединением» в качестве одного из параметров, именно эту переменную я хочу переслать на обратный вызов на следующем шаге. Вот функция query_result:

 template<typename ConnectionType, typename... ResultColumnTypes>
void PostgresCaller::query_result(ozo::error_codeamp;amp; ec, ConnectionTypeamp;amp; connection, std::unique_ptr<PostgresCallerQueryResult<ResultColumnTypes...>> result)
{
    if(ec)
    {
        SVS_TRACE1 << "Postgres query failed. lifetime: " << result->time_alive() << " ms ";

        SVS_WARNING() << get_error_msg(ec, connection);
    }
    else
    {
        SVS_TRACE1 << "Postgres query succeeded. lifetime: " << result->time_alive() << " ms ";

        result->was_success();
    }
    result->callback();
}
 

Моя мысль состоит в том, чтобы передать переменную «connection» в result-> callback() . Выполнимо ли это с помощью std::function или я должен использовать лямбды в качестве обратного вызова и иметь «автоматический соединитель» в качестве одного из параметров?

Комментарии:

1. что вы имеете в виду? я уже использую std::function?

2. Имеет ли connection базовый интерфейс? Как это выглядит std_func ?