传递并调用成员函数(boost :: bind / boost :: function?)

时间:2011-03-09 11:23:30

标签: c++ boost-bind boost-function

我有一个非常简单的问题:传递并调用类中的成员函数。我知道我想使用BOOST绑定(和/或函数),但我还没有真正掌握它的概念。

以下代码编译并执行问题。但是当我想将“f3”函数更改为非静态类函数时,乐趣就开始了:

#include <iostream>
#include <inttypes.h> 
#include <boost/bind.hpp>
#include <boost/function.hpp>

class Test
{
public:
  void f1();
private:
  void f2(void (*callfunc)(uint32_t));
  static void f3(uint32_t x);
};

void Test::f1(){
  f2(f3);
}

void Test::f2(void (*callfunc)(uint32_t)){
  (*callfunc)(42);
}

void Test::f3(uint32_t x){
  std::cout << "x: " << x << std::endl;
}

int main(int argc, char ** argv)
{
  Test ct;
  ct.f1();
  return 0;
}

现在,更改后

static void f3(uint32_t x);

void f3(uint32_t x);

编译器不满意并且告诉我“错误:没有匹配函数来调用'Test :: f2()'”

阅读了一些关于boost :: bind和boost :: function的SO帖子,我想我需要改变f2()的定义以及f1()如何调用f2()给f3()作为目标调用,但除此之外......关于boost :: bind和boost函数的每一个组合,我都试图无法编译。

我该如何写这个?作为一个额外的问题:是否有关于boost :: bind和boost :: function的简单介绍性读物? BOOST文档并没有真正帮助我。

2 个答案:

答案 0 :(得分:8)

boost :: function是一个模板类,它采用函数签名。您还可以使用function0,function1等

boost::function< void(uint32_t) >

定义一个看似函数的“可调用”,即它接受类型uint32_t的单个参数并返回void。

适当的编号模板为function1< void, uint32_t >。这些始终首先指示返回类型,然后按顺序指示参数。

boost::bind是一个非常特殊的函数,可以推导出传递给它的参数并为你创建一个仿函数。

它不会为你创建一个void(uint32_t),它会创建一个模式为一的东西。

因此请将您的签名更改为:

void f2(boost::function<void(uint32_t)>);

然后你可以这样称呼它:

f2( boost::bind( &Test::f3, this, _1 ) );

注意奇怪的_1是一个“占位符”告诉boost :: bind它需要放入参数,在这种情况下是uint32_t

答案 1 :(得分:5)

首先,我将解释删除static给出编译错误的原因:

看看这个签名:

void (*callfunc)(uint32_t)

这是一个指向自由函数的指针,它接受uint32_t并返回void。在f3内将Test声明为

void f3(uint32_t x);

然后f3 是类Test 的成员函数,它接受uint32_t并返回void。因此,没有f3f2期望的参数类型相匹配。

至于如何使用boost::functionboost::bind来提供解决方案:

void Test::f1(){
    boost::function<void (uint32_t)> f = boost::bind(&Test::f3, this, _1);
    f2(f);
}

<强>更新

最后,关于教程:我发现this在过去学习仿函数(boost::functionboost::bind返回)时非常有用。它没有特别提到boost,但是一旦你理解了在较低级别发生了什么,你就会发现使用boost轻而易举。