【问题标题】:Converting pointer to member function to std::function将指向成员函数的指针转换为 std::function
【发布时间】:2017-11-01 03:12:00
【问题描述】:

我有一个稍微复杂的用例,将成员函数指针传递给外部函数,然后由成员函数再次调用(不要问!)。我正在学习 std::functionstd::mem_fn 但我似乎无法转换我的老派函数指针

void (T::*func)(int)std::function<void (T::*)(int) func>

在下面的代码中,我希望能够在来自 anotherMember 的调用中将 std::function 传递给 memFuncTaker

#include "class2.hpp" 
#include <iostream> 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(this, &outer::aMember); 
  } 

}; 


template<class T> 
void memFuncTaker(T* obj , void (T::*func)(int) ){ 
  (obj->*func)(7); 
} 

【问题讨论】:

  • 我没有看到任何尝试在您的代码中使用 std::function
  • 你的问题标题是“Converting pointer to member function to std::function”,但问题听起来像“Converting std::function to pointer to member function”。

标签: c++ c++11 function-pointers member-function-pointers std-function


【解决方案1】:

当您将std::function 绑定到非静态成员函数指针时,它会“显示”隐藏的this 参数,使其成为结果仿函数的第一个显式参数。因此,对于 outer::aMember,您将使用 std::function&lt;void(outer *, int)&gt; 并最终得到一个双参数仿函数

#include <functional>
#include <iostream> 

template<class T> 
void memFuncTaker(T *obj , std::function<void(T *, int)> func){ 
  func(obj, 7);
} 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(this, std::function<void(outer *, int)>{&outer::aMember}); 
  } 
}; 

int main() {
  outer o;
  o.anotherMember(0);
}

http://coliru.stacked-crooked.com/a/5e9d2486c4c45138

当然,如果您愿意,您可以绑定该函子的第一个参数(通过使用 std::bind 或 lambda),从而再次“隐藏”它

#include <functional>
#include <iostream> 

using namespace std::placeholders;

void memFuncTaker(std::function<void(int)> func){ 
  func(7);
} 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(std::function<void(int)>(std::bind(&outer::aMember, this, _1))); 
  } 
}; 

int main() {
  outer o;
  o.anotherMember(0);
}

请注意,在此版本中,memFuncTaker 不再必须是模板(这恰好是 std::function 的主要用途之一 - 采用类型擦除技术来“去模板化”代码)。

【讨论】:

  • std::bind(&amp;outer::aMember, this, _1)的返回类型怎么是std::function&lt;void(int)&gt;。我知道aMember 是一个成员函数,但是this 怎么没有显示绑定到std::function 的函数签名。我预计std::bind(&amp;outer::aMember, this, _1) 会返回std::function&lt;void(outer*, int)&gt;
  • @creationist:为什么? std::bind 的全部目的是消除(绑定)第一个 (outer *) 参数。 之前 std::bind 函子有两个参数 - outer *int,但 之后 std::bind 只剩下一个:int
  • 再举个例子,如果你做std::mem_fn(&amp;outer::aMember),你会得到一个双参数函数(就像你描述的那样)。但是如果在那之后你做std::bind(std::mem_fn(&amp;outer::aMember), this, _1) 只会留下一个参数。你在我上面的回答中看到的是同样的事情,因为std::mem_fn 在这种情况下是可选的,可以省略。 std::bind 足够聪明,可以在不显式应用 std::mem_fn 的情况下理解其含义。
猜你喜欢
  • 1970-01-01
  • 2017-08-27
  • 2021-12-22
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多