Я довольно новичок в программировании и C++. У меня есть функция, которую я хочу принимать в качестве аргумента указателей на функции с шаблонными значениями. Вот что я имею в виду...
у меня есть эта функция:
template<typename... ColumnTypes, typename... ParameterTypes>
void query(std::function<void(bool success, ozo::rows_of<ColumnTypes...>& results)> callback, const
std::string& query, ParameterTypes&& ... parameters);
"ozo::rows_of" является псевдонимом для:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
Я хочу, чтобы каждый запрос был снабжен обратным вызовом, этот обратный вызов должен иметь возможность принимать разные типы. например. "Типы столбцов"
Что я пробовал:
void myfunc(bool succeeded, ozo::rows_of<int>& results)
{
//code
}
postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
результат:
.cpp:241:26: error: no matching member function for call to 'query'
postgres_caller->query(myfunc, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
~~~~~~~~~~~~~~~~~^~~~~
.h:165:22: примечание: шаблон-кандидат проигнорирован: не удалось сопоставить 'function<void (bool, vector<tuple<type-parameter-0-0...>, allocator<tuple<type-parameter-0-0 ...> > > &)>' против 'void (*)(bool, std::vectorstd::tuple<int, std::allocatorstd::tuple<int > > &)' void PostgresCaller::query(std::function<void(bool Success, ozo::rows_of<ColumnTypes...>& results)> обратный вызов, const std::string& query, ParameterTypes&&... параметры)
Я также пробовал с лямбдой:
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
{
//code
}, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
результат:
error: no matching member function for call to 'query'
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
~~~~~~~~~~~~~~~~~^~~~~
.h:165:22: примечание: шаблон-кандидат проигнорирован: не удалось сопоставить 'function<void (bool, vector<tuple<type-parameter-0-0...>, allocator<tuple<type-parameter-0-0 ...> > > &)>' против '(лямбда в .cpp:241:32)' void PostgresCaller::query(std::function<void(bool Success, ozo::rows_of<ColumnTypes...>& results)> обратный вызов, const std::string& query, ParameterTypes&&... параметры) ^
Выполнимо ли это и как это можно сделать? очень признателен. /Джон
Вывод шаблона работает только для точного типа, который вы передаете, поэтому, если вы передаете указатель на функцию, шаблон не может определить, в какой тип std::function
преобразовать этот указатель функции.
Сделайте вызываемый параметр шаблона вместо использования std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
callback( ... ); // use it like this
}
В большинстве случаев вам не нужно выводить сигнатуру обратного вызова. Просто вызовите его с аргументами, которые вы ожидаете от него.
Если этого недостаточно, есть способы вывести сигнатуру обратного вызова, но это становится немного более подробным и большую часть времени не служит реальной цели.
query
ожидаетstd::function
в качестве первого параметра. Вы передаете ему вещи, которые не являются специализациямиstd::function
. Вывод параметров шаблона не учитывает неявные преобразования. Вам нужно будет обернуть обратный вызов в подходящийstd::function
на сайте вызова. Или же переделайтеquery
, чтобы принять произвольный вызываемый объект, если у вас есть контроль над ним.