【问题标题】:test std::function validity after bind to member function绑定到成员函数后测试 std::function 有效性
【发布时间】:2016-01-14 09:01:06
【问题描述】:

对于结构:

struct A {
    int var = 10;
    void check() {
        std::cout << "var is " << var << std::endl;
    }
};

假设我使用动态分配的a 对象创建A::check() 的std::function 对象:

auto a_ptr = std::make_unique<A>();
std::function<void()> f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
f();

如果我可以测试f 以查看绑定的A 对象是否仍然存在,那将是很好的安全性。是否可以直接从f 检索该信息?假设无法从调用点访问a_ptr,因此我无法直接针对a_ptr 进行测试。使用std::function 的运算符bool,或针对nullptr 测试f 不起作用。

【问题讨论】:

  • 你基本上是在问this(假设这是XY problem)?
  • 不确定这是一个 XY 问题,而是使用 std::weak_ptr 并在调用之前检查它是解决此问题的一个不错的解决方案。
  • @TartanLlama :首先使用 bind 而不是 lambda 是导致 IMO XY 问题的原因。

标签: c++ c++11 std-function stdbind


【解决方案1】:

所以您基本上希望您的函数对象测试由a_ptr 管理的A 实例的存在,我看到了使用当前 c++ std 功能执行此操作的 3 种方法。

-- Lambda 引用unique_ptr

auto a_ptr = std::make_unique<A>();
std::function<void()> f = [&] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();

这要求指针在函数对象处于活动状态的任何时候都处于活动状态。

-- 带有shared_ptr副本的Lambda

auto a_ptr = std::make_shared<A>();
std::function<void()> f = [=] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();

同样的事情,但对生命周期关系没有要求,但代价是一些额外的性能成本,主要是共享指针的副本,在大多数情况下可能完全值得它节省的头痛(我会被优化人员)。

-- 智能指针中的自定义删除器可重置您的功能

std::function<void()> f;
auto a_ptr = std::unique_ptr<A, std::function<void(A*)>>(new A, [&](A*){ f = nullptr;});
f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
a_ptr.reset();
if (f)
  f();

这要求你的删除器可以通过某种方式访问​​函数来重置它,无论是直接还是通过你的类中的存储系统(函数容器是一个不错的设计)。


您还可以使用自己的原语创建更精细的系统,但这会使您远离标准库。最终,您必须主要根据对象的生命周期和所有权关系来选择最适合您的情况。

【讨论】:

    【解决方案2】:

    嗯,这个很简单,使用std::shared_ptr

    当您考虑它时,您基本上希望确保程序中的某些实体是有效的,只要有东西在使用它。
    换句话说,您正在寻找shared_ptr

    否则,设计看起来有点奇怪,如果您的程序中的某个单一实体拥有a_ptr,它应该是所有使用此资源的std::functions 的单一所有者,这不是您的意图。如果该所有者不是 std::function 的所有者,那么您将大大增加分段错误、堆损坏和其他您不想要的东西的可能性。

    【讨论】:

      猜你喜欢
      • 2012-08-22
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      相关资源
      最近更新 更多