c ++ 0x:在lambda arity上重载

Der*_*rek 8 c++ lambda c++11

我正在尝试创建一个可以使用带有0,1或2个参数的lambda调用的函数.由于我需要代码在g ++ 4.5和vs2010上工作(它不支持可变参数模板或lambda转换到函数指针),我想出的唯一想法是选择基于arity调用哪个实现.以下是我应该如何看待的非工作猜测.有没有办法修复我的代码或者有更好的方法来执行此操作?

#include <iostream>
#include <functional>
using namespace std;

template <class Func> struct arity;

template <class Func>
struct arity<Func()>{ static const int val = 0; };

template <class Func, class Arg1>
struct arity<Func(Arg1)>{ static const int val = 1; };

template <class Func, class Arg1, class Arg2>
struct arity<Func(Arg1,Arg2)>{ static const int val = 2; };

template<class F>
void bar(F f)
{
    cout << arity<F>::val << endl;
}

int main()
{
    bar([]{cout << "test" << endl;});
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ams 17

lambda函数是具有单个函数调用运算符的类类型.因此,您可以通过获取其地址并使用重载决策来选择要调用的函数来检测该函数调用运算符的arity:

#include <iostream>

template<typename F,typename R>
void do_stuff(F& f,R (F::*mf)() const)
{
    (f.*mf)();
}

template<typename F,typename R,typename A1>
void do_stuff(F& f,R (F::*mf)(A1) const)
{
    (f.*mf)(99);
}

template<typename F,typename R,typename A1,typename A2>
void do_stuff(F& f,R (F::*mf)(A1,A2) const)
{
    (f.*mf)(42,123);
}

template<typename F>
void do_stuff(F f)
{
    do_stuff(f,&F::operator());
}

int main()
{
    do_stuff([]{std::cout<<"no args"<<std::endl;});
    do_stuff([](int a1){std::cout<<"1 args="<<a1<<std::endl;});
    do_stuff([](int a1,int a2){std::cout<<"2 args="<<a1<<","<<a2<<std::endl;});
}
Run Code Online (Sandbox Code Playgroud)

但请注意:这不适用于函数类型,或具有多个函数调用运算符或非const函数调用运算符的类类型.