我们是否可以通过std::mem_fn
使用ref限定成员函数?
以下代码无法编译:
class DeadPool {
public:
void jump() & {
std::cout << "Did not jump\n";
}
void jump() && {
std::cout << "Jumped from helicopter\n";
}
};
int main() {
DeadPool dp1;
//auto cobj = std::mem_fn(&DeadPool::jump); // Won't compile
//cobj(dp1);
//cobj(DeadPool());
using Func = void (DeadPool::*) () &; // lvalue ref qualifier explicitly provided
Func fp = &DeadPool::jump; // This works, as expected
(std::move(dp1).*fp)();
return 0;
}
错误讯息:
mem_fn_ex.cc:18:15:错误:没有匹配函数来调用&#39; mem_fn&#39;
auto cobj = std :: mem_fn(&amp; DeadPool :: jump); //不会编译 ^ ~~~~~~~~~~ / Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/functional:1233:1: 注意:候选人 模板被忽略:无法推断模板参数&#39; _Rp&#39; mem_fn(_Rp _Tp :: * __pm)^ mem_fn_ex.cc:23:18:错误:指向成员的指针 功能类型&#39; Func&#39; (又名&#39; void(DeadPool :: *)()&amp;&#39;)可以 只能在左值上调用(std :: move(dp1)。* fp)(); ~~~~~~~~~~~~~~ ^
编译器:在Clang(3.4)和g ++(5.3)
上我想我可以利用这样一个事实:在std::_Mem_fn
类实现中,调用rvalue对象如下所示:
return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);
这可以很好地调用特定于rvalue this
的成员函数,但由于签名在编译时是不同的,所以它不能这样做。
答案 0 :(得分:4)
问题在于您将重载的函数传递到函数模板中 - mem_fn()
无法推断您想要的 jump()
。您需要使用强制转换传递特定的一个:
auto cobj = std::mem_fn(static_cast<void (DeadPool::*)() &>(&DeadPool::jump));
cobj(dp1); // ok
cobj(DeadPool()); // error
然而,这是一个非常不令人满意的解决方案,因为冗长(这是一个很难打字)和限制(你有&
- 和&&
- 合格的重载有一个原因,但你可以只用一个?)。最好在这里使用通用lambda:
auto jump = [](auto&& pool){ std::forward<decltype(pool)>(pool).jump(); };
jump(dp1); // ok: Did not jump
jump(DeadPool()); // ok: Jumped from helicopter