Função que aceita funções como parâmetro com tipos modelados
Sou bastante novo em programação e C ++. Eu tenho uma função que quero aceitar ponteiros de função com valores modelados como argumento. Aqui está o que quero dizer ...
eu tenho esta função:
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" é o apelido de:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
Quero que cada consulta receba um retorno de chamada, esse retorno de chamada precisará ser capaz de aceitar tipos diferentes. por exemplo. "ColumnTypes"
O que eu tentei:
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: observação: modelo candidato ignorado: não foi possível corresponder 'função <void (bool, vetor <tupla <parâmetro-tipo-0-0 ...>, alocador <tupla <parâmetro-tipo-0-0 ...>>> &)> 'contra' void (*) (bool, std :: vectorstd :: tuple <int, std :: allocatorstd :: tuple <int>> &) 'void PostgresCaller :: query (std :: função <void (sucesso de bool, ozo :: rows_of <ColumnTypes ...> & resultados)> callback, const std :: string & query, ParameterTypes && ... parâmetros)
Eu também tentei com 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: observação: modelo candidato ignorado: não foi possível corresponder 'função <void (bool, vetor <tupla <parâmetro-tipo-0-0 ...>, alocador <tupla <parâmetro-tipo-0-0 ...>>> &)> 'contra' (lambda em .cpp: 241: 32) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & resultados)> retorno de chamada, const std :: string & query, ParameterTypes && ... parameters) ^
Isso é viável e como pode ser feito? muito apreciado. /João
Respostas
A dedução de modelo funciona apenas no tipo exato que você passa, então se você passar um ponteiro de função, o modelo não pode deduzir para qual tipo std::function
converter esse ponteiro de função.
Torne o chamável um parâmetro de modelo, em vez de usar std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
callback( ... ); // use it like this
}
Na maioria das vezes, você não precisa deduzir a assinatura do retorno de chamada. Basta chamá-lo com os argumentos que você espera que ele aceite.
Se isso não for suficiente, também existem maneiras de deduzir a assinatura do retorno de chamada, mas fica um pouco mais prolixo e na maioria das vezes não tem nenhum propósito real.