【问题标题】:Storing functions call and list of parameters to invoke later存储函数调用和稍后调用的参数列表
【发布时间】:2012-10-28 23:25:09
【问题描述】:

我的这段代码由于锁定而面临性能问题。请参阅下面的草图(无论如何不能发布太大的实际代码):

XYZ::process()
{
  ...
  lock();
  processSharedData(id );
  unlock();
  ...
}

XYZ::processSharedData(obj id)
{
  obj a = accessDataAttr1(id);
  //do some integrity checks

  //evaluate some conditions and then
  func1(attr1, attr2, attr3, ...);

  obj b = accessDataAttr2(id);
  //do some integrity checks

  //evaluate some conditions and then
  func2(attr1, attr2, attr3, ...);

  obj c = accessDataAttr3(id);
  //do some integrity checks

  //evaluate some conditions and then
  func3(attr1, attr2, attr3, ...);

  //do some clean up
  return;
}

现在我想将 func1、func2 和 func3 从锁定/解锁范围中移出。请提出有效的方法。有没有办法用它的参数存储函数调用以便以后调用它?

如何将所有参数存储在成员结构中,将函数指针存储在 std::list 中?

编辑:

很抱歉在我还没有 c++11 之前没有提到这一点。任何没有 std:function 和 std:bind 的解决方案现在都很好。

【问题讨论】:

标签: c++ locking


【解决方案1】:

确定你可以这样做:

typedef std::vector<std::function<void(void)>> f_list;

XYZ::process() {
  //our function list
  f_list fl;
  lock();
  fl=processSharedData(id );
  unlock();
  //invoke functions
  for(auto& f : fl) f();
}

f_list XYZ::processSharedData(obj id) {
  f_list fl;
  obj a = accessDataAttr1(id);
  //do some integrity checks

  fl.push_back(
       std::bind(&func1, attr1, attr2, attr3)
  );

  obj b = accessDataAttr2(id);
  //do some integrity checks

  //evaluate some conditions and then
  fl.push_back(
       std::bind(&func2, attr1, attr2, attr3)
  );
  //and so on
  return fl;
}

参考

http://en.cppreference.com/w/cpp/utility/functional/bind

http://en.cppreference.com/w/cpp/utility/functional/function

http://en.cppreference.com/w/cpp/container/vector

【讨论】:

  • 谢谢。看起来不错,但是没有 std:function 和 std::bind 的任何解决方案?
  • 别忘了 bind 和 function 都可以从 boost 中获得
  • 大型产品开发的一部分,因此我无法决定使用新标准/版本。我的公司也没有人使用 boost。
  • @LovelyVirus 我知道您所遇到的问题是一个常见问题,但它仍然很愚蠢。 Boost 是一个具有宽松(商业友好)免费许可证的高质量库。除了这个,我真的帮不了你了。我建议你告诉你的上级,对 C++11 和/或 boost 的这些限制使你的工作变得不必要地困难和/或生产出劣质产品。
  • 我同意你的看法。为什么不使用可用的最新技术?可能对于我们产品的新版本,他们可能会使用它,但我必须解决旧版本中的问题,所以遗憾的是不得不接受可用的东西。不过感谢您的帮助。
【解决方案2】:

以 111111 的答案为基础,如果您要调用的函数是 XYZ 类中的成员函数,则必须将实例作为第一个参数传递:

fl.push_back(
    std::bind(&func1, this, attr1, attr2, attr3)
);

稍后当您调用函数时,您可以使用 C++11 中的另一个新功能:range-based for loop

for (auto f : fl)
    f();

【讨论】:

  • 在回复其他帖子时提到,c++11 对我来说还没有。
猜你喜欢
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多