Función que acepta funciones como parámetro con tipos de plantilla
Soy bastante nuevo en programación y C ++. Tengo una función que quiero aceptar punteros de función con valores de plantilla como argumento. Esto es lo que quiero decir ...
tengo esta función:
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" es un alias para:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
Quiero que a cada consulta se le proporcione una devolución de llamada, esta devolución de llamada deberá poder aceptar diferentes tipos. p.ej. "ColumnTypes"
Lo que he probado:
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);
resultado:
.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: nota: plantilla candidata ignorada: no pudo coincidir 'función <void (bool, vector <tupla <tipo-parámetro-0-0 ...>, asignador <tupla <tipo-parámetro-0-0 ...>>> &)> 'contra' void (*) (bool, std :: vectorstd :: tuple <int, std :: allocatorstd :: tuple <int>> &) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & results)> callback, const std :: string & query, ParameterTypes && ... parámetros)
También probé con lambda:
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
{
//code
}, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
resultado:
error: no matching member function for call to 'query'
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
~~~~~~~~~~~~~~~~~^~~~~
.h: 165: 22: nota: plantilla candidata ignorada: no pudo coincidir 'función <void (bool, vector <tupla <tipo-parámetro-0-0 ...>, asignador <tupla <tipo-parámetro-0-0 ...>>> &)> 'contra' (lambda en .cpp: 241: 32) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & resultados)> devolución de llamada, const std :: string & query, ParameterTypes && ... parámetros) ^
¿Es esto factible y cómo se puede hacer? muy apreciado. /John
Respuestas
La deducción de plantilla solo funciona en el tipo exacto que pasa, por lo que si pasa un puntero de función, la plantilla no puede deducir a qué tipo std::function
convertir ese puntero de función.
Haga que el invocable sea un parámetro de plantilla, en lugar de usar std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
callback( ... ); // use it like this
}
La mayoría de las veces no es necesario deducir la firma de la devolución de llamada. Simplemente llámelo con los argumentos que espera que tome.
Si esto no es suficiente, también hay formas de deducir la firma de la devolución de llamada, pero se vuelve un poco más detallada y la mayoría de las veces no tiene un propósito real.