将C++11中的std::function/mem_fn与成员函数一起使用

Using std::function/mem_fn in C++11 with member functions

本文关键字:函数 成员 一起 fn mem 中的 C++11 std function      更新时间:2023-10-16

长话短说,有没有一种简单/定义的方法可以以简化的方式处理函数对象/lambdas和成员函数?

如果我理解正确,如果我使用std::mem_fn,我需要将正确类型的对象传递给函数调用,即

Object o;
ftncall std::mem_fun(&Object::function);
ftncall(o);

理想情况下,有某种方法可以将o"附加"到该函数对象,可能是作为std::weak_ptr,这样我们就知道o是否被删除了。例如,如果有一种方法可以做一些模糊的事情:

Object o;
ftncall std::mem_fn(&Object::function, o); // Or maybe std::mem_fn<Object>
ftncall();

现在,很明显,(据我所知)这并不存在。有没有一种方法可以包装std::mem_fn,这样我就不会失去std::mem_fn的通用性(和精确性),但可以"附加"o,并且仍然可以很好地与其他函数类型(如std::function)配合使用?理想情况下,我仍然可以像使用std::函数那样使用operator()

目前,我能想到的最好的解决方案是这样一个类:

template<class T>
class MemFunWrapper {
public:
    MemFunWrapper(T* t, std::mem_fun funct) : m_t(t), m_function(funct) {}
    std::mem_fun operator*() { return m_function; }
    T* get() { return m_t; }
private:
    T* m_t;
    std::mem_fun m_function;
}

然后你可以这样使用它:

(*MemFunWrapper)(MemFunWrapper->get(), args...);

但这对我来说似乎很难。此外,我必须为std::函数创建一个等效的类,才能以类似的方式使用它,这似乎很愚蠢,因为我已经可以使用std:函数了。理想情况下,我也可以使用最终产品,而不知道我调用的是成员函数还是常规函数。我知道我在问很多问题——任何方向都会有帮助。非常感谢!

您要查找的是std::bind而不是std::mem_fn:

#include <iostream>
#include <functional>
struct Object
{
  void member()
  {
    std::cout << "yay!" << std::endl;
  }
};
int main()
{
  Object o;
  auto fn = std::bind(&Object::member, o);
  fn();
}

FWIW:有一个建议是在std::mem_fn中添加一个重载,接受对象以包含在C++14中。

在C++11中,我通常发现这是用lambdas最容易做到的:

std::shared_ptr<Object> o = std::make_shared<Object>();
auto ftncall = [o](){ if (o) o->function(); }
ftncall();

或者,没有共享寿命:

Object o;
auto ftncall = [&o](){ o.function(); }
ftncall();

或者具有弱ptr:

std::shared_ptr<Object> o = std::make_shared<Object>();
std::weak_ptr<Object> wo = o;
auto ftncall = [ow](){ if (auto o = wo.lock()) o->function(); }
ftncall();

如果您需要类型擦除,只需将其填充到std::function<void()>中即可。

C++11中的Lambdas可以完成与bind基本相同的工作,而不必依赖库函数来完成,而且我个人觉得它们可读性更强。

在某些情况下,bind可以在C++11中做得更好,但在这一点上,它们是拐角情况(在C++1y中,也会切掉更多的拐角)。