将C++11中的std::function/mem_fn与成员函数一起使用
Using std::function/mem_fn in C++11 with member functions
长话短说,有没有一种简单/定义的方法可以以简化的方式处理函数对象/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中,也会切掉更多的拐角)。
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针