简体   繁体   中英

How does the UnaryFunction look like in std::for_each

I am playing with std::for_each , I could understand the following:

std::vector<int> nums{1,2,3,4,5,6};
std::for_each(nums.begin(), nums.end(), [](int& n) {
  n++;
});

According to the definition, It's not hard to deduct the UnaryFunction f.

template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f);

However, when I have a vector of threads

std::vector<std::thread> threads;

I am fascinated by this particular line of code which blocks and waits for the execution to finish:

std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join))

How does it work? What's the UnaryFunction in this case? std::thread::join takes no parameters so it's not a unary function. What magic does the std::mem_fn do to create the unary function?

Basically - it is equivalent to this:

std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); })

So the std::mem_fun(<ref to member function>) generates a functor which accepts a reference to an instance of the type, and when called with that instance, calls the referenced member function.

std::thread::join does actually take one parameter - it is the hidden (implied) this parameter of type std::thread * . The same is true for any non-static member function: it actually has one more parameter than explicitly declared. std::mem_fn "unhides" the implied this parameter, turning it into a visible parameter.

So, std::mem_fn(&std::thread::join) is indeed an unary function with one parameter of std::thread * type. The resultant function object implements standard INVOKE behavior, meaning that it is also callable with std::thread & argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM