如何将对象类的方法传递为 std::function?
How can I pass a method of an object's class as std::function?
我有一个函数需要获取std::function-type参数。我还有一个指向对象的抽象类型指针。是否可以仅使用对象传递该方法?
函数签名:
void foo(std::function<bool(int i)>);
类示例:
class IBase // interface
{
public:
virtual bool sampleMethod(int i) = 0;
};
class Child1 : public IBase // one of the classes that inherit from IBase
{
public:
bool sampleMethod(int i) override;
};
因此,有以下指针指向其中一个 Child 类的对象:
std::unique_ptr<IBase> ptr;
我想用它来传递 sampleMethod 作为 foo 的参数。 有没有办法使用标准或增强来做到这一点?
您可以使用std::bind
和占位符执行此操作:
foo (std::bind (&IBase::sampleMethod, ptr.get (), std::placeholders::_1));
您还可以使用捕获ptr
的 lambda:
foo ([&ptr] (int i) { return ptr->sampleMethod (i); });
无论哪种情况,正如 Yakk - Adam Nevraumont 所说,请确保ptr
比foo
中对它的任何引用或副本都长寿。
现场演示
这是C++,所以你必须担心一生。 你的问题完全忽略了一生;这是一件坏事。
每当你谈论C++任何事情时,你必须清楚所涉及的一切的生命周期。 明确这一点的一种方法是谈论所有权。 另一种是说一件事是谈论范围。
生命周期:
void foo(std::function<bool(int i)> f);
f
和副本尚不清楚。 如果f
和所有副本都不会活过foo
的出口,那与f
或副本可以活过foo
结束完全不同。
部分原因不是你的错;C++std
库缺少描述"没有状态所有权的可调用对象"(function_ref
)的词汇类型,因此人们使用值语义std::function
。
假设你真正想要的是一个function_ref<void(int)>
,那么你可以这样做:
foo( [&](int i){ return ptr->sampleMethod(i); } );
范围保证(ptr
比foo
调用更久,f
及其副本不会超过foo
)平均寿命。
但是,如果foo
可以保留f
的副本,则有两个问题。 首先,ptr
声称在*ptr
的整个生命周期内拥有独特的所有权;但f
也声称对它想要调用的对象拥有所有权。
更重要的是,std::function
可以被复制;这意味着要么它调用的对象必须被复制,要么我们被迫拥有共享所有权。
那么foo
之后*ptr
需要在外面可用吗?*ptr
的副本是否有意义,还是*ptr
f
副本之间共享所有权? 更多的所有权问题及其答案会改变您问题的正确解决方案。
在一个更完美的世界里,function
、moveonly_function
、function_ref
都会存在,你的选择会告诉你在这里需要什么,并简化独。
我根据保罗的回答开始写这个:
_window.setCursorPosCallback(std::bind(&RenderWorld::mouseCallback, this, std::placeholders::_1,std::placeholders::_2));
但是叮叮当当的叫我改成这样:
_window.setCursorPosCallback([this](auto && x, auto && y) {
mouseCallback(std::forward<decltype(x)>(x), std::forward<decltype(y)>(y));
});
所以这有点酷
- Confusion: decltype vs std::function
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 传递给std::function template的template参数究竟代表什么
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 将函数包装器转换为 std::function
- 类型擦除的std::function与虚拟函数调用的开销
- C++ std::function 对于类 exept 的所有实例都是空的(只有 Visual2019 编译器问题)
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将 lambda 表达式传递给 std::function in C++
- 模板类的部分模板专用化,如 std::function
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 从 std::function in C++ 访问模板化 lambda
- 什么是 std::function::argument_type 的替代品?
- C++派生类重载函数(带有 std::function 参数)不可见
- 如何在 qi 符号表中使用 std::function
- 将 std::function 与模板一起使用
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 我需要在 std::function 上使用 unique_ptr 吗?
- 如何将函数指针从 std::function 传递到 Linux 克隆?