具有Template类的事件系统,该类源自c ++中的非模板基类

时间:2015-01-19 23:48:30

标签: c++ templates

我正在做什么

我正在研究一个事件系统。基本上有任何成员可以插入的“插槽”。他们所需要的只是一个将要收听的事件名称和一个功能。由于存储了所有插槽,我必须将它们存储为类中的变量。

问题

当函数放入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),但我仍然不明白你将如何抓住这个功能。

1 个答案:

答案 0 :(得分:0)

我认为你需要开始接受在某些时候如果你想使用多态对象,你需要在SlotBase中创建一个虚函数。如果你想在使用函数之前在创建时回放你的类型,那么多态就没有意义,因为你已经将原始类型随身携带到了能够这样做的地方,所以为什么要在第一时间进行upcast呢? / p>

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