[英]std::reference_wrapper does not work nicely with std::bind
我试图用std :: bind模拟C ++ 11 lambdas中的完美/移动捕获。 在下面的函数中,我想通过lvalue或rvalue传递带有可变'operator()'的处理程序,根据需要复制或移动它并调用它。
template <typename Handler>
void foo (Handler&& h)
{
std::bind (
[] (Handler& h) { h (); },
std::forward<Handler> (h)
) ();
}
在大多数情况下,此代码工作正常,但在使用std :: ref包装处理程序时失败。 http://coliru.stacked-crooked.com/a/b9c29b6ed6fb5aa8
int main ()
{
int i = 0;
auto x = [i] () mutable { std::cout << "i=" << ++i << "\n"; };
foo (x); // OK
foo (std::move (x)); // OK
foo (std::ref (x)); // Error
return 0;
}
如果我创建自己的' reference_wrapper '实现,它就可以正常工作。 http://coliru.stacked-crooked.com/a/6b302233ab86d9ad :
template <typename T>
struct my_reference_wrapper
{
T& t;
template <typename ...As> auto
operator() (As&&... args) const -> decltype (t (std::forward<As> (args)...))
{
return t (std::forward<As> (args)...);
}
};
template <typename T> inline my_reference_wrapper<T>
my_ref (T& t) { return { t }; }
int main ()
{
int i = 0;
auto x = [i] () mutable { std::cout << "i=" << ++i << "\n"; };
foo (my_ref (x)); // Now OK
foo (my_ref (x)); // And even increments 'i' properly.
return 0;
}
它是std :: bind bug吗?
是否可以使用c ++ 11进行编译并仅使用std库类,而无需重新创建自己的包装器?
std::bind
对reference_wrapper
有特殊处理。
您可以添加重载来处理:
template <typename T>
void foo (std::reference_wrapper<T> h)
{
std::bind ([] (T& t) { t(); }, h) ();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.