我有一个非常简单的问题:传递并调用类中的成员函数。我知道我想使用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文档并没有真正帮助我。
乙
答案 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
。因此,没有f3
与f2
期望的参数类型相匹配。
至于如何使用boost::function
和boost::bind
来提供解决方案:
void Test::f1(){
boost::function<void (uint32_t)> f = boost::bind(&Test::f3, this, _1);
f2(f);
}
<强>更新强>
最后,关于教程:我发现this在过去学习仿函数(boost::function
和boost::bind
返回)时非常有用。它没有特别提到boost
,但是一旦你理解了在较低级别发生了什么,你就会发现使用boost
轻而易举。