std :: bind和std :: weak_ptr

时间:2014-10-21 22:36:01

标签: c++ c++11 gcc

我有一个类创建一个包装器仿函数来处理对象的weak_ptr。当仿函数执行时,它将在调用对象仿函数之前测试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&& ...)

...与平常的模板crud山。 jist是它不能再将Bind :: Weak()中的std :: bind()结果转换为Bind :: Weak()的返回类型。

我已经摆弄了几个小时,现在还没能解决这个问题。

1 个答案:

答案 0 :(得分:1)

问题在于您无法使用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&&都没有多大意义,IMO。