简体   繁体   English

模板类源自C ++中非模板基类的事件系统

[英]Event System with Template class deriving from Non-Template base class in c++

What I'm doing 我在做什么

I'm working on an event system. 我正在开发一个事件系统。 Basically there are "slots" which any member can chime into. 基本上,任何成员都可以插入“插槽”。 All they need is an event name which it will be listening to, and a function. 他们所需要的只是一个将要监听的事件名称和一个函数。 Since all the slots are stored I had to store them as a variable in a class. 由于所有插槽都已存储,因此我必须将它们作为变量存储在类中。

The Problem 问题

The function becomes unavailable when it's placed into the SlotBase class. 将函数放入SlotBase类后,该函数将不可用。 I am wondering if there is a way to retain the function in the Slot class while storing in in the SlotBase class. 我想知道是否有一种方法可以将功能存储在SlotBase类中同时保留在Slot类中。

The Code 编码

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));

I didn't include the code for the integer sequences in the 'std::bind' as it isn't related to the problem. 我没有在'std :: bind'中包含整数序列的代码,因为它与问题无关。

What I have tried 我尝试过的

I know that if I use a Slot cast on the baseS variable that would give me the result but I am unable to do so because I don't know the templates that Slot will have. 我知道,如果我在baseS变量上使用Slot baseS ,这会给我结果,但由于我不知道Slot将拥有的模板,所以无法这样做。

I have seen many similar posts stating to make baseS a pointer (such as here ) but I still don't understand how you would grab the function. 我已经看过许多类似的文章,它们声明将baseS用作指针(例如here ),但是我仍然不明白如何使用该函数。

I think you need to start to accept that at some point if you want to use polymorph objects, you will need to create a virtual function in SlotBase . 我认为,如果要使用多态对象,则需要在某个时候开始接受这一点,您将需要在SlotBase创建一个虚函数。 If you want to cast back to your type at creation before using the function, the polymorphism makes no sense, because you have carried the original type somewhere along with you to be able to do so, so why upcast anyway in the first time ? 如果您想在使用函数之前在创建时回退您的类型,则多态性是没有意义的,因为您已经随身携带了原始类型,所以为什么要在第一时间进行转换?

If you really need to upcast, then you need to think about a RUNTIME solution to get back to access the derived functionality. 如果确实需要升级,则需要考虑RUNTIME解决方案以重新访问派生的功能。 In this case, this would mean you need to create a generic interface to your signals, so try to make a pure virtual method in SlotBase that will pack an undefined number of arguments, and implement that generic caller in your Slot so that it unpacks the arguments in order and calls your slot with the arguments. 在这种情况下,这意味着您需要为信号创建一个通用接口,因此请尝试在SlotBase中创建一个纯虚拟方法,该方法将打包未定义数量的参数,并在您的Slot实现该通用调用程序,以便将其解压缩。依次输入参数,并使用参数调用您的广告位。 I don't know if variadic methods can be overriden though, that seems dubious. 我不知道可变参数方法是否可以覆盖,这似乎是可疑的。 Otherwise you'll have to use boost::any or something to pack the arguments in a runtime collection. 否则,您将不得不使用boost :: any或其他东西将参数打包到运行时集合中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM