std::bind and std::weak_ptr

std::bind and std::weak_ptr

本文关键字:std ptr and bind weak      更新时间:2023-10-16

我有一个类,它创建了一个包装函子来处理对象的weak_ptr。当functor执行时,它将在调用对象functor之前测试weak_ptr。

此外,如果对象不再存在,包装函子可以返回默认值。

这是根据GCC 4.4.7…编译的一个类的摘录

class Bind
{
public:
    // non-void weak-functor
    template <typename R>
    struct Wrapper<R, typename std::enable_if<!std::is_void<R>::value>::type>
    {
        using result_type = R;
        template <typename O>
        R operator()(const std::weak_ptr<O> && obj,
                     std::function<R()> && func, R && ret)
        {
            if (auto ptr = obj.lock())
            {
                return func();
            }
            return std::forward<R>(ret);
        }
    };
    // weak from shared - non-void return
    template <typename R, typename F, typename O, typename... A>
    static std::function<R()> Weak(R && ret,
                                   F func,
                                   const std::shared_ptr<O> && obj,
                                   A&&... args)
    {
        return std::bind(Wrapper<R>(),
                         std::weak_ptr<O>(obj),
                         std::function<R()>(std::bind(func, obj.get(),
                                            std::forward<A>(args)...)),
                         ret);
    }
    // ...
};

类可以这样使用。。。

auto x = std::make_shared<X>();
auto f = Bind::Weak(false, &X::foo, x, 1, 2, 3);
f();   // returns x::foo(1, 2, 3) 
x.reset()
f();   // returns false

不幸的是,在将编译器升级到GCC 4.8.3之后,它不再进行编译。错误开始时是这样的。。。

error: could not convert 'std::bind(_Func&&, _BoundArgs&& ...)

用通常堆积如山的模板污垢。jist是它不能再将bind::Weak()中std::bind()的结果转换为bind::Weak()的返回类型。

我已经处理了几个小时了,还没能解决这个问题。

问题是,使用std::function无法进行完美转发,因为std::function需要可复制,因此绑定值也必须可复制。

operator()原型更改为:

template<typename O>
R operator()(const std::weak_ptr<O>& obj, const std::function<R()>& func, const R& ret)
{
    //...
}

应该或多或少足以使此工作(很难确定,因为您发布的代码不完整)。

但是,现在您对绑定的转发被破坏了,所有这些std::forward&&都没有多大意义