I'm having some trouble understanding something from the notes section for std::bind
on the cppreference page: it says that when duplicate placeholders appear in the same bind expression-such as multiple _1's-the results are only well-defined only if u1 is an lvalue or non-movable rvalue. Can someone give an example where it would not be well-defined?
The following is probably the simplest example I can think of (and considering my familiarity with rvalues, this is pushing my limits).
First the code (probably too simple, but I think it is correct for demonstration):
#include <iostream>
#include <utility>
#include <functional>
struct Obj
{
Obj()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
Obj(Obj const&)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
Obj(Obj&&)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
void foo(Obj, Obj)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
int main()
{
using namespace std::placeholders;
auto fn = std::bind(foo, _1, _1);
fn(Obj());
}
Output
Obj::Obj()
Obj::Obj(Obj &&)
Obj::Obj(Obj &&)
void foo(Obj, Obj)
What is important is the clear evidence only one Obj
was initially constructed, but was subsequently "moved" twice, which is a no-no for move-semantics. Once the first move is complete, the object is in purgatory. The second move is not well-defined, since the source object is no longer well-defined. The repetitive placeholder cannot be a movable rvalue or what you see here can happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With