C++ 传递函数作为具有多态类型的参数

标签 c++ polymorphism

我有函数

void addOnHover(std::function<void(Button&, HoverState)>& func);
void addOnHover(void(*fptr)(Button&, HoverState));

按钮继承ButtonBase ,这是接口(interface)类,我想通过

void hoverOver(game::ButtonBase& button, game::HoverState state)
{
    static int i = 0;
    if (state == game::HoverState::STATE_ENTER)
        std::cout << "entered " <<    button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
    else if (state == game::HoverState::STATE_LEAVE)
        std::cout << "left " << button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
    else
        std::cout << "inside " << button.getLabel().getText().getString().toAnsiString() << " " << ++i << "\n";
}

假设b类型为 Button

但如果我这样做 b.addOnHover(hoverOver);它不会编译(一些古怪的编译器错误,一如既往地遇到这种工作人员)。

如果我这样做,我就能让它工作 b.addOnHover(std::function<void(game::Button&, game::HoverState)>(hoverOver);或者如果我将 hoverOver 更改为 game::ButtonBase&game::Button& ,但我想知道是否可以在没有这种冗长(std::function...)的情况下完成,同时将参数保持为 game::ButtonBase&因为以后可能会有更多的Button类

根据 Bolov 的要求,这是传递 hoverOver 时的编译器错误

1>Source.cpp(58): error C2664: 'void game::Button::addOnHover(std::function<_Fty> &)' : cannot convert parameter 1 from 'void (__cdecl *)(game::ButtonBase &,game::HoverState)' to 'std::function<_Fty> &'
1>          with
1>          [
1>              _Fty=void (game::Button &,game::HoverState)
1>          ]

编辑:

一个可能的解决方案,即使仍然很冗长,也是添加

template <class T, class C, class Q>
std::function<void(T&, C)> wrap(Q ptr)
{
    return std::function<void(T&, C)>(ptr);
}

然后调用b.addOnHover(game::wrap<game::Button, game::HoverState>(hoverOver);但我不确定它是否会正常运行

最佳答案

您遇到的一个问题是非常量左值引用不能绑定(bind)到右值。

制作

void addOnHover(const std::function<void(Button&, HoverState)>& func);

或(最好):

void addOnHover(std::function<void(Button&, HoverState)> func);

对于您的版本,参数 func 是一个非常量左值,当您这样调用它时 b.addOnHover(hoverOver) hoverOver 是指向函数的指针,因此创建了 std::func(右值)类型的临时对象,正如我所说,它不能绑定(bind)到非常量左值引用。

顺便说一句,我在看到错误消息时就明白了这一点,因此尝试解决错误很重要。

关于C++ 传递函数作为具有多态类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21513344/

相关文章:

c++ - 将 shared_ptr 传递给 OpenGL?

c++ - 无法显示比 CDC 区域更高分辨率的位图

c++ - 如何使用多态性优雅地转换 switch+enum

c++ - Qt 根据参数类型触发不同的信号

c++ - 关于 C++ 中接口(interface)类的使用

java - 基于子类的抽象类中的@Inject

c++ - 同时学习 C++ 和 Qt 的最佳方法是什么?

C++ 私有(private)复制构造函数问题

c++ - 使用atof将字符串转换为double

c++ - 使用非虚拟析构函数扩展基类是否危险?