Funktion, die Funktionen als Parameter mit Schablonentypen akzeptiert
Ich bin ziemlich neu in Programmierung und C ++. Ich habe eine Funktion, die ich Funktionszeiger mit Vorlagenwerten als Argument akzeptieren möchte. Hier ist was ich meine ...
Ich habe diese Funktion:
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" ist ein Alias für:
template <typename ... Ts>
std::vector<std::tuple<Ts...>>
Ich möchte, dass jede Abfrage mit einem Rückruf versehen wird. Dieser Rückruf muss in der Lage sein, verschiedene Typen zu akzeptieren. z.B. "ColumnTypes"
Was ich versucht habe:
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);
Ergebnis:
.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: Hinweis: Kandidatenvorlage ignoriert: Konnte nicht mit 'function <void (bool, vector <tuple <type-parameter-0-0 ...>, allocator <tuple <type-parameter-0-0 übereinstimmen ... >>> &)> 'gegen' void (*) (bool, std :: vectorstd :: tuple <int, std :: allocatorstd :: tuple <int> &) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & results)> Rückruf, const std :: string & query, ParameterTypes && ... Parameter)
Ich habe es auch mit Lambda versucht:
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
{
//code
}, "SELECT length FROM this_table WHERE id > $1 AND id < $2;", 11, 14);
Ergebnis:
error: no matching member function for call to 'query'
postgres_caller->query([](bool succeeded, ozo::rows_of<int>& results)
~~~~~~~~~~~~~~~~~^~~~~
.h: 165: 22: Hinweis: Kandidatenvorlage ignoriert: Konnte nicht mit 'function <void (bool, vector <tuple <type-parameter-0-0 ...>, allocator <tuple <type-parameter-0-0 übereinstimmen ... >>> &)> 'gegen' (Lambda bei .cpp: 241: 32) 'void PostgresCaller :: query (std :: function <void (bool success, ozo :: rows_of <ColumnTypes ...> & Ergebnisse)> Rückruf, const std :: string & query, ParameterTypes && ... Parameter) ^
Ist das machbar und wie geht das? sehr geschätzt. /John
Antworten
Der Vorlagenabzug funktioniert nur für den genauen Typ, den Sie übergeben. Wenn Sie also einen Funktionszeiger übergeben, kann die Vorlage nicht ableiten, in welche Art std::function
dieser Funktionszeiger konvertiert werden soll.
Machen Sie den aufrufbaren Parameter zu einem Vorlagenparameter, anstatt ihn zu verwenden std::function
.
template<typename Callable, typename... ParameterTypes>
void query(Callable callback, const std::string& query, ParameterTypes&& ... parameters) {
callback( ... ); // use it like this
}
Meistens müssen Sie die Signatur des Rückrufs nicht ableiten. Nennen Sie es einfach mit den Argumenten, die Sie erwarten.
Wenn dies nicht ausreicht, gibt es auch Möglichkeiten, die Signatur des Rückrufs abzuleiten, aber es wird etwas ausführlicher und dient meistens keinem wirklichen Zweck.