Функция, принимающая функции как параметр с шаблонными типами
Я новичок в программировании и 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...>>
Я хочу, чтобы каждый запрос был снабжен обратным вызовом, этот обратный вызов должен иметь возможность принимать разные типы. например. "ColumnTypes"
Что я пробовал:
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 ...> & результаты)> обратный вызов, 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
}
В большинстве случаев вам не нужно выводить подпись обратного вызова. Просто вызовите его с аргументами, которые вы ожидаете от него.
Если этого недостаточно, есть способы вывести сигнатуру обратного вызова, но он становится немного более подробным и в большинстве случаев не служит реальной цели.