Sto provando a creare una funzione modello a cui è possibile passare qualche altra funzione con qualsiasi tipo e numero di parametri e associarla a un std::function
. Sono riuscito a fare questo:Modelli variabili, tipo deduzione e std :: funzione
#include <iostream>
#include <functional>
int foo(int bar)
{
std::cout << bar << std::endl;
return bar;
}
template <typename Ret, typename... Args>
std::function<Ret (Args...)> func(std::function<Ret (Args...)> f)
{
return f;
}
int main()
{
//auto barp = func(foo); // compilation error
auto bar = func(std::function<void (int)>(foo));
bar (0); // prints 0
}
Vorrei chiamare solo auto barp = func(foo);
e hanno i tipi dedurre, ma questa linea dà i seguenti errori di compilazione:
error: no matching function for call to ‘func(void (&)(int))’
auto barp = func(foo);
^
note: candidate is:
note: template<class Ret, class ... Args> std::function<_Res(_ArgTypes ...)> func(std::function<_Res(_ArgTypes ...)>)
std::function<Ret (Args...)> func(std::function<Ret (Args...)> f)
^
note: template argument deduction/substitution failed:
note: mismatched types ‘std::function<_Res(_ArgTypes ...)>’ and ‘int (*)(int)’
auto barp = func(foo);
^
Perché è cercando di abbinare std::function<_Res(_ArgTypes ...)>
con int (*)(int)
? Sento che dovrei ottenere in qualche modo il compilatore per espandere _Res(_ArgTypes ...)
a int(int)
, ma come?
Perché la conversione in un 'std :: function' a tutti? 'std :: function' è una classe di cancellazione dei tipi: prende le informazioni sul tipo di ciò da cui è costruita e ne cancella la maggior parte. La deduzione di tipo prende il suo argomento, ne deduce il tipo e genera codice. Stai chiedendo di dedurre di che tipo cancellare qualcosa. È come creare un'armatura che crea pistole per sparare a chi la indossa; il tipo di cancellazione è l'opposto * della deduzione del tipo nella maggior parte dei sensi. Raramente è una buona idea. È possibile, ma il C++ ha pochi motivi per renderlo * facile * Hai un caso pratico? – Yakk
E i sovraccarichi o gli elenchi di argomenti variabili? Solo in alcune circostanze è possibile. Puoi comunque usare cose come boost function_traits. – tahsmith
@Yakk, stavo cercando di codificare una funzione di "memoization", nel senso che restituirebbe un callable con gli stessi parametri e restituirà il tipo del suo argomento che chiamerebbe la funzione originale eccetto che cercherebbe i valori calcolati precedenti (da conservare in una mappa adatta). Vorrei usare 'std :: function' per memorizzare la funzione originale. Non sono sicuro che sia possibile. – Tarc