【问题标题】:std::mem_fn with ref_qualified member functions带有 ref_qualified 成员函数的 std::mem_fn
【发布时间】:2016-11-27 08:42:41
【问题描述】:

有什么方法可以通过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:错误:没有匹配的函数调用“mem_fn”
自动 cobj = std::mem_fn(&DeadPool::jump); // 不会编译 ^~~~~~~~~~~ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/functional:1233:1: 注:候选人 模板被忽略:无法推断模板参数“_Rp”mem_fn(_Rp _Tp::* __pm)^ mem_fn_ex.cc:23:18:错误:指向成员的指针 函数类型 'Func' (aka 'void (DeadPool::*)() &') 可以 只能在左值上调用 (std::move(dp1).*fp)(); ~~~~~~~~~~~~~~^^

编译器:在 Clang(3.4) 和 g++ (5.3) 上

我想我可以利用这样一个事实,在std::_Mem_fn 类实现中,一个右值对象被如下调用:

return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...);

这可能很好地调用了特定于右值this 的成员函数,但由于在编译时签名不同,它不能这样做。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    问题是您将重载函数传递给函数模板 - mem_fn() 无法推断出 哪个 jump() 您想要。你需要通过一个特定的演员:

    auto cobj = std::mem_fn(static_cast<void (DeadPool::*)() &>(&DeadPool::jump));
    cobj(dp1);        // ok
    cobj(DeadPool()); // error
    

    但是,由于冗长(键入很多)和限制(您有 &amp;- 和 &amp;&amp;- 限定的重载是有原因的,但您只能使用一个? )。最好在这里使用通用 lambda:

    auto jump = [](auto&& pool){ std::forward<decltype(pool)>(pool).jump(); };
    jump(dp1);         // ok: Did not jump
    jump(DeadPool());  // ok: Jumped from helicopter
    

    【讨论】:

    • 这让我想到为什么 this 没有基于 ref 限定符重载。有什么想法吗?
    • @Arunmu 这和这个问题有什么关系?
    • 好吧,如果编译器以这种方式实现它,那么有问题的代码可能会起作用。
    • @Arunmu 不,它不会。问题中的代码不起作用,因为编译器无法推断 &amp;DeadPool::jump 的类型(这是一个重载的名称 - 没有要推断的单一类型)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2015-10-03
    • 2013-02-11
    • 2015-07-18
    相关资源
    最近更新 更多