Ho scritto un codice che recupera i tipi dei parametri non automatici quando viene fornita una funzione lambda generica. Come puoi vedere nel codice qui sotto, l'idea è di chiamare la funzione connect con un lambda generico e fornire argomenti per i parametri auto (che saranno sempre in primo piano nel mio caso d'uso). Quindi nel codice qui sotto il mio obiettivo era rilevare che il secondo parametro è di tipo float.Rilevamento dei tipi di parametri da lambda - errore di compilazione generico con GCC
Il codice funziona bene con clang 3.8 ma non è compilato con gcc 6.1.1, quindi mi chiedevo se si trattava di un bug in gcc o se questo non è valido codice C++? Posso supporre che un lambda generico sia implementato con una funzione operatorata() o questo compilatore sia specifico?
template <typename Functor, typename... AllArgs, typename... ProvidedArgs>
void findArgTypes(void(Functor::*)(AllArgs...) const, Functor, ProvidedArgs...)
{
// AllArgs == int, float
// ProvidedArgs == int
}
template <typename Func, typename... ProvidedArgs>
void connect(Func func, ProvidedArgs... providedArgs)
{
findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...);
}
int main()
{
int tmp = 0;
connect([&](auto, float){ ++tmp; }, 0);
}
L'errore che gcc dà è questo:
main.cpp: In instantiation of ‘void connect(Func, ProvidedArgs ...) [with Func = main()::<lambda(auto:1, float)>; ProvidedArgs = {int}]’:
main.cpp:16:33: required from here
main.cpp:11:17: error: no matches converting function ‘operator()’ to type ‘void (struct main()::<lambda(auto:1, float)>::*)() const’
findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...);
~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:16:27: note: candidate is: template<class auto:1> main()::<lambda(auto:1, float)>
connect([](auto, float){}, 0);
^
Rimozione del const
nel findArgTypes dà lo stesso risultato.
utilizzando il seguente codice funziona con entrambi i compilatori:
struct Foo
{
template <typename T>
void operator()(T, float) const {}
};
int main()
{
Foo f;
connect(f, 0);
}
Questo codice sembra compilare con gcc ma non con clang. Ma cambiare il mio codice per prendere 'void (*) (AllArgs ...)' come primo parametro di findArgTypes dà ancora lo stesso errore con gcc (e non funziona più con clang). Anche la cattura di una variabile locale non sembra fare la differenza. – texus
Hai bisogno di due funzioni sovraccariche - una per le funzioni libere, una per le funzioni oggetto - o semplicemente cambia un po 'il tuo design ... – PiotrNycz
clang potrebbe essere sbagliato - vedi esempio dalla pagina collegata: 'int & (* fpi) (int *) = [] (auto * a) -> auto & {return * a; }; // ok' – PiotrNycz