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.
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
首先,我将解释删除它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::function和boost::bind返回)时很有用.它没有boost具体提及,但是一旦你理解了在较低级别发生了什么,你会发现使用boost微风.