std::for_each 中的 UnaryFunction 是什么样子的

How does the UnaryFunction look like in std::for_each

我正在玩 std::for_each,我可以理解以下内容:

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

根据定义,一元函数f不难推导

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

但是,当我有一个线程向量时

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

我对这一行阻塞并等待执行完成的特定代码着迷:

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

它是如何工作的?这种情况下的 UnaryFunction 是什么? std::thread::join 不接受任何参数,因此它不是一元函数。 std::mem_fn 创建一元函数有什么魔力?

基本上-它等同于:

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

因此 std::mem_fun(<ref to member function>) 生成一个仿函数,它接受对该类型实例的引用,并在使用该实例调用时调用引用的成员函数。

std::thread::join 实际上有一个参数——它是 std::thread * 类型的隐藏(隐含)this 参数。对于任何非静态成员函数也是如此:它实际上比显式声明的参数多一个参数。 std::mem_fn "unhides" 隐含的 this 参数,将其变为可见参数。

所以,std::mem_fn(&std::thread::join)确实是一个一元函数,只有一个std::thread *类型的参数。结果函数对象实现标准 INVOKE 行为,这意味着它也可以使用 std::thread & 参数调用。