我很困惑为什么需要 std::mem_fn
。
我有一个函数接受任何可调用对象(lambda、函数指针等),并将其绑定(bind)到一个参数。
例如:
template<class T>
void Class::DoBinding(T callable) {
m_callable = std::bind(callable, _1, 4);
}
//somewhere else
Item item;
m_callable(item);
我见过的所有代码示例都是:
//some defined member function
Item::Foo(int n);
DoBinding(std::mem_fn(&Item::Foo));
为什么不能简单地是:
DoBinding(&Item::Foo);
后者似乎无需使用 std::mem_fn 即可调用,那么为什么需要它呢?
最佳答案
这是因为需要 UnaryFunction
或 BinaryFunction
的通用代码将使用常规调用语法直接调用它。所以选择一个任意算法,如 for_each
,它可以像这样实现:
template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
for (; first != last; ++first) {
f(*first); // <== N.B. f(*first)
}
return f;
}
如果您使用 &Item::Foo
调用了 for_each()
,代码会尝试调用 (&Item::Foo)(x)
,这是错误的,因为对于指向成员的指针,您必须编写 (x.*&Item::Foo)()
。 mem_fn
旨在解决的正是这种语法差异:mem_fn
处理指向成员的指针的调用语法,因此您可以将所有算法与指向成员的指针以及函数和函数对象。你不能有 for_each(v.begin(), v.end(), &Item::Foo)
但你可以有 for_each(v.begin(), v.end(), mem_fn(&Item::Foo))
。
这在 std::bind()
(以及 std::thread
和 std::function
和 ... ) native ,因为它们都对指向成员的指针进行了显式处理。由于 DoBinding()
本身调用 std::bind()
,因此在这种情况下没有理由使用 std::mem_fn
.
是是一个消除这种句法差异的提议:P0312 .它并不顺利。
关于c++ - 为什么要使用 mem_fn?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37259529/