#c #templates
#c #шаблоны
Вопрос:
я довольно новичок в программировании и C . У меня есть функция, которую я хочу принимать указатели на функции с шаблонными значениями в качестве аргумента. Вот что я имею в виду…
у меня есть эта функция:
template<typename... ColumnTypes, typename... ParameterTypes>
void query(std::function<void(bool success, ozo::rows_of<ColumnTypes...>amp; results)> callback, const
std::stringamp; query, ParameterTypesamp;amp; ... parameters);
«ozo::rows_of» является псевдонимом для:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
Я хочу, чтобы каждый запрос был снабжен обратным вызовом, этот обратный вызов будет необходим, чтобы иметь возможность принимать разные типы. например. «ColumnTypes»
Что я пробовал:
void myfunc(bool succeeded, ozo::rows_of<int>amp; 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<кортеж<тип-параметр-0-0 …>, распределитель<кортеж<тип-параметр-0-0…> > > amp;)>’ против «недействительности (*)(bool, std::vectorstd::tuple<int, std::allocatorstd::tuple<int > > amp;)’
void PostgresCaller::query(std::function<void(bool success, ozo::rows_of<ColumnTypes…>amp; результаты)> обратный вызов, conststd::stringamp; query, ParameterTypesamp;amp; … параметры)
Я тоже пробовал с лямбдой:
postgres_caller->query([](bool succeeded, ozo::rows_of<int>amp; 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>amp; results)
~~~~~~~~~~~~~~~~~^~~~~
.h:165:22: примечание: игнорируется шаблон кандидата: не удалось сопоставить ‘function<void (bool, vector<кортеж<тип-параметр-0-0 …>, распределитель<кортеж<тип-параметр-0-0…> > > amp;)>’ против ‘(лямбдав .cpp:241:32)’
void PostgresCaller::query(std::function<void(bool success, ozo::rows_of<Типы столбцов …>amp; результаты)> обратный вызов, const std::stringamp; query, ParameterTypesamp;amp; … параметры)
^
Выполнимо ли это и как это можно сделать? очень признателен. /Джон
Комментарии:
1.
query
ожидаетstd::function
в качестве первого параметра. Вы передаете ему вещи, которые не являются специализациямиstd::function
. Вычет параметров шаблона не учитывает неявные преобразования. Вам придется обернуть обратный вызов в подходящийstd::function
на сайте вызова. Или изменитеquery
дизайн, чтобы принимать произвольный вызываемый объект, если у вас есть над ним контроль.
Ответ №1:
Вычет шаблона работает только с точным типом, который вы передаете, поэтому, если вы передаете указатель на функцию, шаблон не может определить, в какой тип std::function
преобразовать этот указатель на функцию.
Сделайте вызываемый параметр шаблонным параметром вместо использования std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::stringamp; query, ParameterTypesamp;amp; ... parameters) {
callback( ... ); // use it like this
}
В большинстве случаев вам не нужно выводить сигнатуру обратного вызова. Просто вызовите его с теми аргументами, которые вы ожидаете от него получить.
Если этого недостаточно, есть способы также вывести сигнатуру обратного вызова, но это становится немного более подробным и большую часть времени не служит никакой реальной цели.