Undefined results using std :: bind and duplicate placeholders

I am having trouble understanding anything from the notes section for std::bind on the cppreference page: it says that when duplicate placeholders appear in the same bind expression since there are several _1's - the results are only well defined only in that in case u1 is an lvalue or non-movable rvalue. Can someone give an example where it will not be clearly defined?

+6
source share
1 answer

Perhaps this is the simplest example I can come up with (and given my familiarity with rvalues, this pushes my limitations).

At first the code (maybe too simple, but I think this is right for the 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) 

The important thing is that initially only one Obj was built, but subsequently it was "moved" twice , which does not matter for move-semantics. As soon as the first move is completed, the object is in purgatory. The second move is not correct, since the source object is no longer correct. A repeating placeholder cannot be a movable value or what you see here can happen.

+7
source

Source: https://habr.com/ru/post/974285/


All Articles