【问题标题】:How can I use polymorphism with std::function?如何在 std::function 中使用多态性?
【发布时间】:2013-08-11 14:53:15
【问题描述】:

假设我有 2 个班级:

class A {}

class B : public A {}

我想使用std::function 接收 A 类型的任何内容,但分配给它接收从 A 继承的类的方法(如 B)。

void myFun(B bbbb) {}

std::function<void(A)> blah = std::bind(myFun, _1);

这显然行不通,因为编译器不会隐式地向下转换。

但是我怎么能做这样的事情呢?基本上,我想保存一些基本 std::function 类型的映射,并且在每个映射值中,它将一个 std::function 保存到像 B 这样的派生类型。

有没有办法将强制转换运算符绑定到占位符?

【问题讨论】:

  • 由于并非所有As 都保证为Bs,因此这是不安全的。
  • @Dave 没错,但我们假设映射是正确的,它总是会得到正确的类型。
  • 如果是这样,你为什么不能让std::function 采用B 类型?如果它比这更复杂,也许你应该模板它?
  • (显然,如果你真的想破解它,只需让函数接受 A 并转换它)
  • 使用引用或指针,例如std::function&lt;void(A const&amp;)&gt; blah = std::bind(myFun, _1);。多态性通过两者起作用。

标签: function c++11 bind std-function


【解决方案1】:

好的,最后我刚刚做了一个解决方法。
编译器不会让你隐式转换,所以我绑定了一个转换方法。
所以,为了保持它的通用性和模板化,它是这样的:

首先,一个获取函数参数类型的辅助类:

template <typename T>
class GetFunctionArgumentVal;

template <class T, typename U >
class GetFunctionArgumentVal<std::function<U(T)>>
{
public:
    typedef T arg;
    typedef U returnVal;
};

然后,使用 static_cast 进行类型转换的转换运算符(保持编译时类型安全),然后使用派生类调用函数:

template <typename FUNCTION, typename BASE>
void castAndCall(FUNCTION bf, BASE& temp) 
{
    bf(static_cast< GetFunctionArgumentVal<FUNCTION>::arg >(temp));
}

使用示例:

class A {};

class B : public A {};

class C : public A {};

void targetB(B& temp) 
{

}

void targetC(C& temp) 
{

}

    std::function<void(A &)> af;
    std::function<void(B &)> bf = targetB;
    std::function<void(C &)> cf = targetC;

    B b;
    C c;

    af = std::bind(castAndCall<decltype(bf),A>,bf,std::placeholders::_1);
    af(b);

    af = std::bind(castAndCall<decltype(cf),A>,cf,std::placeholders::_1);
    af(c);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多