【问题标题】:std::bind and std::weak_ptrstd::bind 和 std::weak_ptr
【发布时间】:2014-12-17 07:37:47
【问题描述】:

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

...与通常的大量模板杂物。关键是它不能再将 Bind::Weak() 中 std::bind() 的结果转换为 Bind::Weak() 的返回类型。

我已经解决了这个问题几个小时,但无法解决问题。

【问题讨论】:

  • 你已经abused std::forward
  • x 不是右值,因此它似乎不太可能绑定到Bind::Weak 中的右值引用obj

标签: c++ c++11 gcc


【解决方案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&amp;&amp; 都没有多大意义,IMO。

【讨论】:

  • 就是这样。非常感谢。
猜你喜欢
  • 2016-07-31
  • 2016-08-03
  • 1970-01-01
  • 2020-08-06
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
相关资源
最近更新 更多