Jon*_*an. 12 c++ stdbind c++11
我很困惑为什么std::mem_fn
需要.
我有一个函数,它接受任何可调用的(lambda,函数指针等),并将它绑定到一个参数.
例如:
template<class T>
void Class::DoBinding(T callable) {
m_callable = std::bind(callable, _1, 4);
}
//somewhere else
Item item;
m_callable(item);
Run Code Online (Sandbox Code Playgroud)
我见过的所有代码示例都是:
//some defined member function
Item::Foo(int n);
DoBinding(std::mem_fn(&Item::Foo));
Run Code Online (Sandbox Code Playgroud)
为什么不能简单地:
DoBinding(&Item::Foo);
Run Code Online (Sandbox Code Playgroud)
似乎后者可以调用而不必使用std :: mem_fn,那么为什么需要呢?
Bar*_*rry 19
这是因为通用代码期望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;
}
Run Code Online (Sandbox Code Playgroud)
如果你打电话for_each()
跟&Item::Foo
,代码尝试调用(&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
...),因为它们都有明确处理指向成员的指针.而且由于DoBinding()
自己打电话std::bind()
,std::mem_fn
在这种情况下没有理由.
这里是被提议摆脱这个语法差别:p0312中.它进展不顺利.
Nic*_*las 12
这通常是因为写入的人DoBinding(std::mem_fn(&Item::Foo))
不知道DoBinding
可以直接获取成员指针.
记住:std::sort(..., &Item::Foo)
会失败,因为sort
期望值是可直接调用的函数对象.成员指针不是.实际上,当给定成员指针而不是直接可调用类型时,C++标准库中的每个算法都会失败.你DoBinding
唯一的工作,因为你正在使用std::bind
,它有成员指针的特殊重载.打电话的DoBinding
人不一定知道你在做那件事.
大多数通过模板参数获取callable的代码都会阻塞成员指针.所以为了安全起见,我们不会将成员指针作为可以直接调用的对象传递; 用mem_fn
它把它变成这样一个对象.