我想将不同类型但签名相同的函子传递给方法。因此我得出结论,应该使用 std::function 。但是由于这个方法还应该存储对函数对象的引用,所以我想传递一个 shared_ptr 来代替(用于生命周期管理)。下面的代码适用于 B 类(b.run(...)),但无法为 A 类编译(a.run(...) 中断)。当传递一个指针而不是函数对象本身时,这个转换问题的原因是什么?我该如何规避它?
#include <functional>
#include <memory>
class MyFunctor
{
public:
void operator()(const float &f)
{}
};
template<class FunSig>
class A
{
public:
void run(std::shared_ptr<std::function<FunSig> > f_ptr)
{
// store f_ptr in a vector
}
};
template<class FunSig>
class B
{
public:
void run(std::function<FunSig> f)
{}
};
int main()
{
MyFunctor mf1;
std::shared_ptr<MyFunctor> mf2_ptr(new MyFunctor);
A<void (const float &)> a;
B<void (const float &)> b;
a.run(mf2_ptr); // this breaks!
b.run(mf1); // this works
}
编译器错误:
error: no matching function for call to ‘A<void(const float&)>::run(std::shared_ptr<MyFunctor>&)’
note: candidate is:
note: void A<FunSig>::run(std::shared_ptr<std::function<FunSig> >) [with FunSig = void(const float&)]
note: no known conversion for argument 1 from ‘std::shared_ptr<MyFunctor>’ to ‘std::shared_ptr<std::function<void(const float&)> >
现在我发现如果 MyFunctor 从 std::function 继承,a.run(...) 可以编译:
class MyFunctor : public std::function<void (const float &)>
为什么现在可以使用?如果函子中不需要更改代码,我会更好。