是否有一种简单的方法可以使用匹配的函数签名转发到成员函数?

时间:2010-06-24 21:55:04

标签: c++ visual-c++ c++11

是否有一种简单的方法可以使用匹配的函数签名转发到成员函数?

typedef std::tr1::function<int(int,int,int,int)> TheFn;
class C
{
    int MemberFn(int,int,int,int) { return 0; }

    TheFn getFn() { 
        //is there a simpler way to write the following line?
        return [this](int a,int b,int c,int d){ return this->MemberFn(a,b,c,d); };
    } 
};

2 个答案:

答案 0 :(得分:1)

您是否尝试过bind

// C++0x update
struct test {
   void f( int, int, int, int );
};
int main()
{
   std::function<void (int,int,int,int)> fn;
   test t;
   fn = std::bind( &t::f, &t, 
           std::placeholders::_1, 
           std::placeholders::_2, 
           std::placeholders::_3, 
           std::placeholders::_4 );
   fn( 1, 2, 3, 4 ); // t.f( 1, 2, 3, 4 )
}

我已经完全保留了所有元素的资格,但std::placeholders应用了很多次并没有真正帮助提高可读性...我想using std::placeholders根本不会受到伤害:

using std::placeholders;
fn = std::bind( &t::f, &t, _1, _2, _3, _4 );

编辑:为了使它更接近问题代码,以便更清楚它具有与原始代码完全相同的功能:

typedef std::function<int(int,int,int,int)> TheFn;
class C {
   int MemberFn( int, int, int, int ) { return 0; }
public:
   int MemberFn2(int,int,int,int) { return 2; }
   TheFn getFn() {
      using std::placeholders;
      return std::bind( &C::MemberFn, this, _1, _2, _3, _4 );
   }
};
int main() {
   C instance;
   TheFn fn1 = instance.getFn();
   std::cout << fn1( 1, 2, 3, 4 ) << std::endl; // 0

   using std::placeholders;
   TheFn fn2 = std::bind( &C::MemberFn2, &instance, _1, _2, _3, _4 );
   std::cout << fn2( 1, 2, 3, 4 ) << std::endl;
}

正如您在两种情况下所看到的那样,您也在做同样的事情。我在示例中使用了私有和公共方法来显示当您bind时,会在绑定位置检查成员方法访问级别,而不是在调用位置。因此,即使MemberFn在课程中是私有的,您也可以通过绑定的仿函数调用它。如果该成员是公共成员,您实际上可以从该类外部绑定。

答案 1 :(得分:0)

有可能用Boost :: Lambda制作一些东西,但实际上,我建议不要这样做,除了你可能会发现使用尾随返回类型比显式typedef更容易。另外,据我所知,当你捕获这个时,作为一个特殊情况,那么lambda成为一个成员lambda,就像它一样,你不需要明确的this-&gt;。