Ottieni il tipo di parametro lambda

Vorrei un modo per ottenere il primo tipo di parametro di una funzione lambda, è ansible?

per esempio

invece di:

template struct base { virtual bool operator()(T) = 0; } template struct filter : public base { virtual bool operator()(T) override {return /*...*/ } }; template filter make_filter(F func) { return filter(std::move(func)); } auto f = make_filter([](int n){return n % 2 == 0;}); 

Mi piacerebbe:

 template struct filter : public base<typename param1::type> { bool operator()(typename param1::type){return /*...*/ } }; template filter make_filter(F func) { return filter(std::move(func)); } auto f = make_filter([](int n){return n % 2 == 0;}); 

Sulla base della risposta di Xeo, questo è quello che ho ottenuto lavorando su VS2010:

 template struct arg1_traits_impl; template struct arg1_traits_impl{typedef A1 arg1_type;}; template struct arg1_traits_impl{typedef A1 arg1_type;}; template typename arg1_traits_impl::arg1_type arg1_type_helper(T); template struct filter : public base<typename std::decay::type> { bool operator()(typename std::decay::type){return /*...*/ } }; template filter make_filter(F func) { return filter(std::move(func)); } 

Ho provato a semplificare il codice, ma ogni tentativo sembra spezzarlo.

L’opzione più semplice sarebbe semplicemente rendere l’ operator() un modello stesso:

 template struct filter { template void operator(Arg&& arg){ // use std::forward(arg) to call the stored function } }; template filter make_filter(F func) { return filter(std::move(func)); } auto f = make_filter([](int n){return n % 2 == 0;}); 

Ora, teoricamente , il seguente codice dovrebbe funzionare . Tuttavia, non con MSVC10 grazie a un bug:

 #include  #include  template struct function_traits; template struct function_traits { typedef T type; }; template void bar(F f){ typedef typename function_traits< decltype(&F::operator())>::type signature; std::cout << typeid(signature).name(); } int main(){ bar([](int n){ return n % 2 == 0; }); } 

Ecco un esempio su come sarebbe con GCC. MSVC10, tuttavia, semplicemente non compila il codice. Vedi questa mia domanda per ulteriori dettagli. Fondamentalmente, MSVC10 non tratta decltype(&F::operator()) come tipo dipendente. Ecco un work-around che è stato ideato in una discussione di chat :

 #include  #include  #include  template struct function_traits; template struct function_traits { // non-const specialization typedef A1 arg_type; typedef R result_type; typedef R type(A1); }; template struct function_traits { // const specialization typedef A1 arg_type; typedef R result_type; typedef R type(A1); }; template typename function_traits::type* bar_helper(T); template void bar(F f){ typedef decltype(bar_helper(&F::operator())) fptr; typedef typename std::remove_pointer::type signature; std::cout << typeid(signature).name(); } int main(){ bar([](int n){ return n % 2 == 0; }); }