Существует ли простой способ пересылки функции-члена с соответствующей сигнатурой функции? - PullRequest
1 голос
/ 25 июня 2010

Есть ли простой способ пересылки функции-члена с соответствующей сигнатурой функции?

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 ]

1 голос
/ 25 июня 2010

Вы пробовали 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 является закрытым внутри класса, вы можете вызвать его через связанный функтор. Если член общедоступный, вы можете связываться вне класса.

0 голосов
/ 25 июня 2010

Может быть возможно сделать что-то из Boost :: Lambda, но в действительности я бы посоветовал этого не делать, за исключением того, что вам может оказаться проще использовать конечный тип возврата, чем явно typedef.Кроме того, насколько я знаю, когда вы фиксируете это как особый случай, тогда лямбда становится как бы лямбда-членом, и вам не требуется явное выражение this ->.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...