Ответ 1
Самый простой вариант - просто сделать operator()
сам шаблон:
template<typename F>
struct filter
{
template<class Arg>
void operator(Arg&& arg){
// use std::forward<Arg>(arg) to call the stored function
}
};
template<typename F>
filter<F> make_filter(F func)
{
return filter<F>(std::move(func));
}
auto f = make_filter([](int n){return n % 2 == 0;});
Теперь, теоретически, следующий код должен работать. Однако это не связано с MSVC10 благодаря ошибке:
#include <iostream>
#include <typeinfo>
template<class FPtr>
struct function_traits;
template<class T, class C>
struct function_traits<T (C::*)>
{
typedef T type;
};
template<class F>
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; });
}
Здесь пример о том, как он будет выглядеть с GCC. Однако MSVC10 просто не компилирует код. Подробнее см. этот вопрос. В принципе, MSVC10 не рассматривает decltype(&F::operator())
как зависимый тип. Здесь была обложка, которая была разработана в обсуждении чата :
#include <iostream>
#include <typeinfo>
#include <type_traits>
template<class FPtr>
struct function_traits;
template<class R, class C, class A1>
struct function_traits<R (C::*)(A1)>
{ // non-const specialization
typedef A1 arg_type;
typedef R result_type;
typedef R type(A1);
};
template<class R, class C, class A1>
struct function_traits<R (C::*)(A1) const>
{ // const specialization
typedef A1 arg_type;
typedef R result_type;
typedef R type(A1);
};
template<class T>
typename function_traits<T>::type* bar_helper(T);
template<class F>
void bar(F f){
typedef decltype(bar_helper(&F::operator())) fptr;
typedef typename std::remove_pointer<fptr>::type signature;
std::cout << typeid(signature).name();
}
int main(){
bar([](int n){ return n % 2 == 0; });
}