【问题标题】:C++0x bind and function without copy-construction没有复制构造的 C++0x 绑定和函数
【发布时间】:2011-03-08 16:54:43
【问题描述】:

我目前正在尝试一些新的 C++0x 功能,即 std::function 和 std::bind。这两个函数似乎非常适合用于 C++ 的事件委托系统,其工作方式类似于 C♯。我之前尝试过自己创建类似委托的东西,但是我需要的成员函数指针的黑客对我来说太多了……

在我的测试中,我注意到 std::bind 会复制您绑定的每个对象。虽然这肯定会提高安全性 - 不能删除仍然注册的事件处理程序 :) - 这也是有状态对象的问题。有没有办法停用复制 - 或者至少有办法再次从 std::function 获取封装的对象?

PS: 是否有关于将包含在 C++0x(希望是 C++11!)中的功能的参考资料,最后它在 TR1 的主要部分和一些补充……

我尝试了 cppreference.org,但他们仍处于文档编制的早期阶段,另一方面 cplusplus.com 似乎甚至还没有开始涵盖 C++0x。

【问题讨论】:

  • 现在,您可以随时参考 boost.bind 和 boost.function 文档。我还发现 en.highscore.de/cpp/boost 很有用。
  • 谢谢,我认为“新”实现是从 boost 派生的,但经过了改编……

标签: function boost c++11 bind


【解决方案1】:

如果您想避免复制,请使用std::ref 和/或std::cref。他们将对象包装到伪引用中

【讨论】:

    【解决方案2】:

    这不太对:

    我注意到 std::bind 复制每个 您绑定的对象。

    至少这不是预期的规范。您应该能够将不可复制的对象移动到绑定中:

    std::bind(f, std::unique_ptr<int>(new int(3)))
    

    然而,现在只移动对象存储在活页夹中,它是一个左值。因此,您只能在f 接受左值仅移动对象(例如通过左值引用)时调用它。如果这是不可接受的,并且如果源对象的寿命比活页夹长,那么使用 std::ref 是另一个很好的解决方案(如 Armen 所述)。

    如果您需要复制绑定的对象,那么它的所有绑定参数都必须是可复制的。但是如果你只移动构造绑定的对象,那么它只会移动构造它的绑定参数。

    最好的参考是N3242。我知道还没有一个好的和全面的教程。我可能会从 the boost documentation 开始,并理解 std::bind 已尽可能地适应 rvalue-refs。

    【讨论】:

    • 我会重新表述:绑定对象后,我可以删除它,并且稍后在调用函数时仍会调用它 -> 必须是原始对象的副本已删除!
    • 我最近有一个关于这个的问题:stackoverflow.com/questions/5126219/…(即用std::bind 转发右值引用)。
    【解决方案3】:

    我创建了一个移动兼容版本的绑定。它仍然存在很多问题,例如 binders 构造函数和一些 buggylines 等,但它似乎可以工作

    在这里查看 http://code-slim-jim.blogspot.jp/2012/11/perfect-forwarding-bind-compatable-with.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 2015-07-24
      • 2011-07-15
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多