Функция, принимающая функции в качестве параметра с шаблонными типами

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

В большинстве случаев вам не нужно выводить сигнатуру обратного вызова. Просто вызовите его с теми аргументами, которые вы ожидаете от него получить.

Если этого недостаточно, есть способы также вывести сигнатуру обратного вызова, но это становится немного более подробным и большую часть времени не служит никакой реальной цели.