6

我有一个可能令人尴尬的简单问题:传递和调用类中的成员函数。我知道我想使用 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 文档在那里并没有真正帮助我。

B.

4

2 回答 2

8

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

boost::function< void(uint32_t) >

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

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

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

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

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

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

然后你可以这样称呼它:

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

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

于 2011-03-09T11:55:37.973 回答
5

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

看看这个签名:

void (*callfunc)(uint32_t)

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

void f3(uint32_t x);

thenf3类的成员函数,Test它接受uint32_t并返回void。因此,没有与预期f3的参数类型匹配的。f2

至于如何boost::function以及boost::bind可以用来提供解决方案:

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

更新:

最后,关于一个教程:我发现在过去学习函子(它是什么boost::functionboost::bind返回)时很有用。它没有boost具体提及,但是一旦您了解了较低级别的确切情况,您就会boost轻而易举地发现。

于 2011-03-09T11:28:21.503 回答