Funktion, die Funktionen als Parameter mit Schablonentypen akzeptiert

Dec 18 2020

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

1 super Dec 18 2020 at 23:02

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::functiondieser 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.