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.