Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C++; 原谅我问这个基本问题的无知,但我已经习惯了使用Python,在这种情况下,我完全忘记了我将如何在C++中尝试这个问题。_C++_Boost_Boost Bind - Fatal编程技术网

如何在C++; 原谅我问这个基本问题的无知,但我已经习惯了使用Python,在这种情况下,我完全忘记了我将如何在C++中尝试这个问题。

如何在C++; 原谅我问这个基本问题的无知,但我已经习惯了使用Python,在这种情况下,我完全忘记了我将如何在C++中尝试这个问题。,c++,boost,boost-bind,C++,Boost,Boost Bind,我希望能够将回调传递给在后台执行缓慢进程的函数,并在进程完成后调用它。此回调可以是自由函数、静态函数或成员函数。我还希望能够为上下文插入一些任意的参数。(即,在某种程度上实现一个非常糟糕的人的协同程序。)除此之外,这个函数将始终采用std::string,这是进程的输出。我不介意这个参数在最终回调参数列表中的位置是否是固定的 我觉得答案将涉及boost::bind和boost::function,但我无法计算出创建任意可调用项(同时将它们转换为仅获取单个字符串)、将它们存储在后台进程中所需的精确

我希望能够将回调传递给在后台执行缓慢进程的函数,并在进程完成后调用它。此回调可以是自由函数、静态函数或成员函数。我还希望能够为上下文插入一些任意的参数。(即,在某种程度上实现一个非常糟糕的人的协同程序。)除此之外,这个函数将始终采用std::string,这是进程的输出。我不介意这个参数在最终回调参数列表中的位置是否是固定的


我觉得答案将涉及boost::bind和boost::function,但我无法计算出创建任意可调用项(同时将它们转换为仅获取单个字符串)、将它们存储在后台进程中所需的精确调用,并使用string参数正确调用callable。

听起来像是要使用。

回调应存储为
boost::function
。然后,您可以通过绑定其他参数,使用
boost::bind
将任何其他函数签名“转换”为此类对象

例子 我没有试图编译这个,但它应该显示出总体思路

void DoLongOperation(boost::function<void, const std::string&> callback)
{
  std::string result = DoSomeLengthyStuff();
  callback(result);
}


void CompleteRoutine1(const std::string&);
void CompleteRoutine2(int param, const std::string&);

// Calling examples
DoLongOperation(&CompleteRoutine1); // Matches directly
DoLongOperation(boost::bind(&CompleteRoutine2, 7, _1)); // int parameter is bound to constant.

// This one is thanks to David Rodríguez comment below, but reformatted here:
struct S 
{ 
  void f( std::string const & );
};

int main() 
{ 
  S s;
  DoLongOperation( boost::bind( &S::f, &s, _1 ) ); 
}
void-dolong操作(boost::函数回调)
{
std::string result=DoSomeLengthyStuff();
回调(结果);
}
void CompleteRoutine1(const std::string&);
void CompleteRoutine2(int参数,const std::string&);
//举例
dolong操作(&CompleteRoutine1);//直接匹配
dolong操作(boost::bind(&CompleteRoutine2,7,_1));//int参数绑定到常量。
//这一条要感谢大卫·罗德里格斯(David Rodríguez)在下面的评论,但在这里重新格式化:
结构
{ 
void f(std::string const&);
};
int main()
{ 
S S;
dolong操作(boost::bind(&S::f,&S,_1));
}
最简单的方法:

class Callback
{
public:
  virtual ~Callback() {}
  virtual Callback* clone() const = 0;

  // Better to wrap the call (logging, try/catch, etc)
  void execute(const std::string& result) { this->executeImpl(result); }

protected:
  // Don't make sense to have them public
  Callback() {}
  Callback(const Callback&) {}
  Callback& operator=(const Callback&) { return *this; }

private:
  virtual void executeImpl(const std::string& result) = 0;
};

// Example
class Example: public Callback
{
public:
  Example(int a, int b): Callback(), mA(a), mB(b) {}
  virtual Example* clone() const { return new Example(*this); }

private:
  virtual void executeImpl(const std::string& result) {}

  int mA;
  int mB;
};

然后,您可以(通过指针/引用)将回调类传递给进程。该类具有所需的状态,必要时可以复制(如果没有,请删除克隆)。

Don;传递一个回调函数,传递一个对象。我真的不明白你为什么认为你必须给它注入动力。对象,schmobject。回调摇滚!;)@尼尔:啊,我明白你的意思了。我的意思是,在链的末端,会有某种类型的适当功能。(因为这最终是你完成事情的方式。)但我没想到会在这里直接通过;我希望能通过引用其中的一个函子,这篇白皮书提供了许多方法来编写C++中合理的通用回调,虽然读起来很简洁,但它可能会对你的利益有好处;啊,我希望我知道在这种情况下“利用绑定或类型擦除”是什么意思。:)我不能对需要通知的对象强加接口要求。他们唯一的要求就是拥有一个正确签名的函数。事实上,我将要调用的东西甚至不能保证是一个对象。它可能是一个免费函数。你能举个例子吗?(或指向特定示例的链接)我已经有了一个好主意,boost::function和boost::bind可以实现我想要的功能,但我不知道如何实现它。+1对于成员函数示例:
struct S{void f(std::string const&);};int main(){S;DoLongOperation(boost::bind(&S::f,&S,_1));}
如果你想添加额外的参数,请记住,
boost::bind
将复制这些参数。不幸的是,这似乎需要从回调中为我拥有的每个调用站点派生一个新类,这是我绝对希望避免的。是和否,每个功能只需要一个类,这对我来说并不不合理。毕竟,每个功能不都有一个函数吗?回调的典型用法是一行程序调用例程,并在最后传递希望它调用的函数。在更复杂的情况下,从成员函数转换为自由函数或添加额外参数可能需要2或3行(例如boost::bind)。这是10行或11行,相比之下太笨拙了。是的,对于一行来说,它可能有点笨拙:)我以为您已经考虑了完全成熟的回调,在这种情况下,再多几行并不重要,因为它们与函数体本身相比,数量级少了一个数量级。