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

BaC*_*aCh 6 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;
}
Run Code Online (Sandbox Code Playgroud)

现在,改变之后

static void f3(uint32_t x);
Run Code Online (Sandbox Code Playgroud)

void f3(uint32_t x);
Run Code Online (Sandbox Code Playgroud)

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

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

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

B.

Cas*_*Cow 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)>);
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用它:

f2( boost::bind( &Test::f3, this, _1 ) );
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*Jon 5

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

看看这个签名:

void (*callfunc)(uint32_t)
Run Code Online (Sandbox Code Playgroud)

这是一个指向自由函数的指针,它接受uint32_t并返回void.什么时候f3在里面宣布Test

void f3(uint32_t x);
Run Code Online (Sandbox Code Playgroud)

然后f3类的成员函数,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);
}
Run Code Online (Sandbox Code Playgroud)

更新:

最后,关于一个教程:我发现在过去学习仿函数(这是什么boost::functionboost::bind返回)时很有用.它没有boost具体提及,但是一旦你理解了在较低级别发生了什么,你会发现使用boost微风.