I'm trying to emulate perfect/move capturing in C++11 lambdas with std::bind. In the function below I'd like to pass handler with mutable 'operator()' by lvalue or by rvalue, copy or move it as needed and call it.
template <typename Handler>
void foo (Handler&& h)
{
std::bind (
[] (Handler& h) { h (); },
std::forward<Handler> (h)
) ();
}
This code works fine in most cases, but fails when I wrap handler with 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;
}
If I create my own 'reference_wrapper' implementation, it works just fine. 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;
}
Is it std::bind bug?
Is it possible to make it compile with c++11 and using only std library classes, without reinventing own wrappers?