Fonction acceptant des fonctions comme paramètre avec des types modèles

Dec 18 2020

im assez nouveau en programmation et C ++. J'ai une fonction que je veux accepter des pointeurs de fonction avec des valeurs modèles comme argument. Voici ce que je veux dire ...

j'ai cette fonction:

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" est un alias pour:

template <typename ... Ts>
   std::vector<std::tuple<Ts...>> 

Je veux que chaque requête soit fournie avec un rappel, ce rappel devra être en mesure d'accepter différents types. par exemple. "ColumnTypes"

Ce que j'ai essayé:

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);

résultat:

.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: note: modèle candidat ignoré: ne peut pas correspondre à 'function <void (bool, vector <tuple <type-parameter-0-0 ...>, allocator <tuple <type-parameter-0-0 ...>>> &)> 'contre' 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 && ... paramètres)

J'ai aussi essayé avec 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);

résultat:

error: no matching member function for call to 'query'
    postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
    ~~~~~~~~~~~~~~~~~^~~~~

.h: 165: 22: note: modèle candidat ignoré: ne peut pas correspondre à 'function <void (bool, vector <tuple <type-parameter-0-0 ...>, allocator <tuple <type-parameter-0-0 ...>>> &)> 'contre' (lambda à .cpp: 241: 32) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & résultats)> callback, const std :: string & query, ParameterTypes && ... paramètres) ^

Est-ce faisable et comment le faire? très appréciée. /John

Réponses

1 super Dec 18 2020 at 23:02

La déduction de modèle ne fonctionne que sur le type exact que vous transmettez, donc si vous transmettez un pointeur de fonction, le modèle ne peut pas déduire le type de std::functionconversion de ce pointeur de fonction.

Faites de l'appelable un paramètre de modèle, au lieu d'utiliser std::function.

template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
    callback( ... ); // use it like this
}

La plupart du temps, vous n'avez pas besoin de déduire la signature du rappel. Appelez-le simplement avec les arguments que vous attendez de lui.

Si cela ne suffit pas, il existe également des moyens de déduire la signature du rappel, mais cela devient un peu plus détaillé et la plupart du temps ne sert à rien.