#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
?