我有一个类创建一个包装器仿函数来处理对象的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()的返回类型。
我已经摆弄了几个小时,现在还没能解决这个问题。
答案 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。