我有一个需要获取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或boost做到这一点?
你可以用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
的f
副本之间是否有意义或共享所有权?更多的所有权问题,以及它们的答案会改变您的问题的正确解决方案。
在一个更完美的世界中,*ptr
,function
,moveonly_function
都将存在,你的选择将在这里告知你需要什么并简化解决方案。