【问题标题】:Event System with Template class deriving from Non-Template base class in c++具有从 C++ 中的非模板基类派生的模板类的事件系统
【发布时间】:2015-03-18 02:27:52
【问题描述】:

我在做什么

我正在开发一个事件系统。基本上有任何成员都可以加入的“插槽”。他们所需要的只是一个它将要监听的事件名称和一个函数。由于存储了所有插槽,因此我必须将它们作为变量存储在一个类中。

问题

该函数在放入 SlotBase 类时变得不可用。我想知道是否有办法在存储在 SlotBase 类中的同时保留 Slot 类中的函数。

代码

class SlotBase { };
//              TC - Template Class
//                              TA - Template Arguments (types)
template <class TC, typename ...TA>
class Slot : public SlotBase  {
public:
    Slot(TC* funcClass, void(TC::*func)(TA...)) {
        SetSlot(funcClass, func);
    }
    template <int ...Is>
    void SetSlot(TC* funcClass, void(TC::*func)(TA...), int_sequence<Is...>) {
        function = std::bind(func, funcClass, placeholder_temp<Is>{}...);
    }
    void SetSlot(TC* funcClass, void(TC::*func)(TA...)) {
        SetSlot(funcClass, func, make_int_sequence<sizeof...(TA)>{});
    }
    std::function<void(TA...)> returnFunction(){
        return function;
    }
private:
    std::function<void(TA...)> function;
};


//...


class RandomClass {
public:
    void randomFunction(int a, float b, int c){ //do stuff };
}


//...


RandomClass randC;
SlotBase baseS;

Slot newSlot(&randC, &RandomClass::randomFunction);
baseS = newSlot;


//...
//Later on down the line when an event was found matching slot call slot function


baseS.returnFunction()(//Correct arguments go here - leaving this out (a lot more code));

我没有在“std::bind”中包含整数序列的代码,因为它与问题无关。

我尝试过的

我知道如果我在 baseS 变量上使用 Slot 强制转换会给出结果,但我无法这样做,因为我不知道 Slot 将拥有的模板。

我看到很多类似的帖子都说要让baseS成为一个指针(比如here),但我还是不明白你会如何获取这个函数。

【问题讨论】:

  • retain the function in the Slot class while storing in in the SlotBase class. 是什么意思?在不知道它的类型的情况下如何存储它?你的意思是你想存储一个不带参数的绑定函数(即所有参数都是绑定的)?
  • @JohnZwinck 是的,我只需要存储函数,将要发送的参数将在稍后出现。我需要能够稍后调用该函数(这就是我所说的保留)。现在,该功能正在被切片,所以我无法访问它。如果我将SlotBase 设为指针,它将不会被切片,但我仍然无法访问它。我不能在返回函数的基类中编写函数,因为它不知道类型。我拥有基类(SlotBase)的唯一原因是能够存储模板类(Slot)。
  • 如何在 SlotBase 中创建一个纯虚函数来检索函数?然后,您将在派生(模板)类中实现它。
  • @JohnZwinck 这是我的第一个想法,但我不必在 SlotBase 类中定义返回类型吗?
  • 是的,返回类型可以是一个不带参数的函数,即完全绑定的函数。如果你需要返回多种不同的类型,好吧,我想你可以创建另一个类层次结构,其中包含一个可以返回的基类,但我不知道重点是什么。

标签: c++ templates


【解决方案1】:

我认为你需要开始接受,如果你想使用多态对象,你需要在SlotBase 中创建一个虚函数。如果您想在使用函数之前在创建时转换回您的类型,那么多态性毫无意义,因为您已经随身携带了原始类型以便能够这样做,那么为什么第一次还是向上转换?

如果您真的需要向上转型,那么您需要考虑一个 RUNTIME 解决方案来返回访问派生的功能。在这种情况下,这意味着您需要为信号创建一个通用接口,因此请尝试在 SlotBase 中创建一个纯虚方法,该方法将打包未定义数量的参数,并在您的 Slot 中实现该通用调用者所以它按顺序解包参数并使用参数调用您的插槽。我不知道是否可以覆盖可变参数方法,这似乎是可疑的。否则,您将不得不使用 boost::any 或其他东西将参数打包到运行时集合中。

【讨论】:

    猜你喜欢
    • 2019-11-09
    • 2016-08-17
    • 2014-03-13
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多