我很困惑当我们绑定到成员变量时boost :: bind会做什么.通过绑定到成员函数,我们实际上创建了一个函数对象,然后调用它向它传递通过占位符提供或延迟并替换的参数.
但是这个表达在幕后做了什么:
boost::bind(&std::pair::second, _1);
Run Code Online (Sandbox Code Playgroud)
用什么替代占位符_1?
我从一篇关于boost :: bind的文章中读到这个例子时发现了这个:
void print_string(const std::string& s) {
std::cout << s << '\n';
}
std::map<int,std::string> my_map;
my_map[0]="Boost";
my_map[1]="Bind";
std::for_each(
my_map.begin(),
my_map.end(),
boost::bind(&print_string, boost::bind(
&std::map<int,std::string>::value_type::second,_1)));
Run Code Online (Sandbox Code Playgroud)
我正在设置一个成员函数作为我正在使用的C库的回调.C库设置如下的回调:
typedef int (*functionPointer_t)(myType1_t*, myType2_t*, myType3_t*);
setCallback(param1, param2, functionPointer, param4)
Run Code Online (Sandbox Code Playgroud)
我想使用boost :: bind(如果可能的话)传入函数指针.我希望指向的函数是实例化类的成员,而不是静态成员.例如
Class A {
public:
A();
protected:
int myCallback(myType1_t*, myType2_t*, myType3_t*); //aka functionPointer_t
}
Run Code Online (Sandbox Code Playgroud)
可以使用boost :: bind和boost :: function来完成吗?Per 如何将类成员函数作为回调传递?(第3个答案)似乎我可以声明以下内容(某处或作为typedef):
boost::function<int (A*, myType1_t*, myType2_t*, myType3*> myCallbackFunction
Run Code Online (Sandbox Code Playgroud)
然后在A(ctor)的某处调用boost :: bind在该类型上,并将其传递给C库调用.
这可能吗,还是我不在基地?非常感谢.
如果嵌入在boost::bind返回对象中的函数指针是NULL/ nullptr/ 0,我需要采取除调用之外的操作.如何确定对象是否包含空函数指针?
boost::functions,因为boost::bind返回对象与模板函数中的不同调用签名一起使用.Run Code Online (Sandbox Code Playgroud)template <typename BRO> Retval do_stuff(BRO func, enum Fallback fallback) { if (func == NULL) { return do_fallback(fallback); } else { return use_retval(func()); } } do_stuff(boost::bind(FuncPtrThatMightBeNull, var1, var2), fallback);
由于被调用者中的函数的arity没有改变,我可以将绑定返回对象"转换"为a boost::function和call.empty()
Retval do_stuff(boost::function<Retval()> func, enum Fallback fallback)
{
if (func.empty())
return do_fallback(fallback);
else
return use_retval(func());
}
Run Code Online (Sandbox Code Playgroud) 我试图理解下面的例子,它类似于(但不相同)之前发布的SO 帮助理解boost :: bind占位符参数:
#include <boost/bind.hpp>
#include <functional>
struct X {
int value;
};
int main() {
X a = { 1 };
X b = { 2 };
boost::bind(std::less<int>(),
boost::bind(&X::value, _1),
boost::bind(&X::value, _2))
(a, b);
}
Run Code Online (Sandbox Code Playgroud)
这怎么可能,最外层绑定函数知道它必须将第一个参数传递给第二个绑定(期望_1),第二个参数传递给第三个绑定(期望_2)?我看到这个的方式是首先评估内部绑定器,因此它们成为两个一元函数对象,稍后传递给less<int>对象的绑定器.当用两个对象调用新创建的功能对象时,a转到第一个内部绑定,然后b转到第二个内部绑定.如果我是对的,我们会使用_1两次.我一定是错的.我将再次重复我的问题以使我的问题清楚:外部绑定器如何知道哪个占位符用于哪个内部绑定器?
class A
{
bool OutofRange(string& a, string& b, string c);
void Get(vector <string>& str, string& a, string& b);
}
void A::Get(vector <string>& str, string& a, string& b)
{
str.erase(
std::remove_if (str.begin(), str.end(), BOOST_BIND(&A::OutOfRange, a, b, _1)),
str.end()
);
}
Run Code Online (Sandbox Code Playgroud)
我收到的错误如下:
Error 7 error C2825: 'F': must be a class or namespace when followed by '::' File:bind.hpp
Error 8 error C2039: 'result_type' : is not a member of '`global namespace'' t:\3rdparty\cpp\boost\boost-1.38.0\include\boost\bind.hpp 67
Run Code Online (Sandbox Code Playgroud)
有人能告诉我我做错了什么吗?
#include <QtCore/QCoreApplication>
#include <boost/bind.hpp>
#include <boost/function.hpp>
class button
{
public:
boost::function<void()> onClick;
boost::function<void(int ,double )> onClick2;
};
class player
{
public:
void play(int i,double o){}
void stop(){}
};
button playButton, stopButton;
player thePlayer;
void connect()
{
//error C2298: 'return' : illegal operation on pointer to member function expression
playButton.onClick2 = boost::bind(&player::play, &thePlayer);
stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
connect();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud) 我有一个可能非常简单的问题:在类中传递并调用成员函数.我知道我想使用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 :: …
假设我已经分配了堆A*,我希望将其作为参数传递给boost::bind.
boost::bind保存以供稍后处理某些STL的容器boost::functions.
我想确保A*在销毁STL容器时销毁.
示范:
A* pA = new A();
// some time later
container.push_back(boost::bind(&SomeClass::HandleA, this, pA);
// some time later
container is destroyed => pA is destroyed too
Run Code Online (Sandbox Code Playgroud)
怎么做到呢?
编辑
也许我想要的不是那么现实.
我有原始指针和函数接收原始指针.通过boost :: bind延迟调用.此时我想要自动内存管理,以防boost :: bind想要执行.我很懒,所以我想使用"准备好"的智能指针解决方案.
std :: auto_ptr看起来像个好人,但是......
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, pAutoA);
Run Code Online (Sandbox Code Playgroud)
不编译(见这里)
auto_ptr<A> pAutoA(pA);
container.push_back(boost::bind(&SomeClass::HandleA, this, boost::ref(pAutoA));
Run Code Online (Sandbox Code Playgroud)
pAutoA被破坏,删除了底层的pA.
编辑02
在上面提到的容器中,我将需要使用不同的参数存储misc"回调".其中一些是对象的原始指针.由于代码是旧的,我并不总是可以改变它.
编写自己的包装器来存储容器中的回调是最后的手段(可能是唯一的),因此是赏金.
绑定函数(使用Boost Bind)时是否存在任何性能影响(正面或负面)?
我使用 CentOS 6.6 (gcc 4.4.7) 并使用 Boost.Asio (1.41) 进行开发。我希望 io_servicerun()在m启动时调用管理器对象中的成员函数。我试图编译的代码如下所示:
#include <memory>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
boost::asio::io_service io;
std::unique_ptr<manager> m;
m = std::make_unique<manager>;
io.post(boost::bind(&manager::run, &m));
Run Code Online (Sandbox Code Playgroud)
gcc 对boost::bind声明进行了匹配,其中包括:
/usr/include/boost/bind/mem_fn_template.hpp:40: error: pointer to
member type ‘void (manager::)()’ incompatible with object type
‘std::unique_ptr<manager, std::default_delete<manager> >’
Run Code Online (Sandbox Code Playgroud)
我想在这里做什么?
manager 对象只会知道计时器;一个了解 io_service 的单独对象稍后将被添加到其构造函数中。但我们的想法是manager::run()创建一组初始计时器来引导系统。
澄清:
我的想法是,外部代码块管理 的生命周期,m下一条语句将是io.run(). 外部代码将m在io.run()返回时销毁。因此,为mto传递原始引用io是合适的。但我是一个现代 C++ 新手,在这里可能会偏离基础。
boost-bind ×10
c++ ×10
boost ×8
c++11 ×2
auto-ptr ×1
bind ×1
boost-asio ×1
gcc ×1
performance ×1