gpt4 book ai didi

c++ - 在虚拟成员函数上使用模板的替代方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 21:34:01 26 4
gpt4 key购买 nike

我正在创建一个简单的事件系统,其中多个监听器可以收到有关特定主题的通知,并且当事件被触发时,它可以将通用有效负载传递给事件,并且监听器将匹配被触发事件的格式。但是,由于无法在虚函数上使用模板,我还能如何实现这一点?

class AEventListener
{
public:

template<class T>
struct PayloadObject {
T obj;
};

explicit AEventListener();
virtual ~AEventListener();

//error here because T is undefined. Each PayloadObject may have a different type
virtual void notify(vector<shared_ptr<PayloadObject<T>>> payload) = 0;
};

通知方法在事件主题有一个监听器订阅时被调用,但我想要一个通用的方法来将随机对象的负载传递给监听器。

例如

fireEvent("test.topic", Payload { 0, "hello", 123 });
//...
listener.notify(payload);

我如何在 C++ 中处理这个问题?


我已经设法解决了这个问题,尽管我认为这不是最好的方法并且可能会降低性能。

template<class T>
struct PayloadObject : public APayloadObject {
T obj;

PayloadObject(T obj) {
this->obj = obj;
}

~PayloadObject() override {

};

};

struct APayloadObject {
virtual ~APayloadObject();
};

射击:

vector<shared_ptr<APayloadObject>> payload;
payload.push_back(shared_ptr<PayloadObject<int>>(new PayloadObject<int>(5))); //payload[0] = int - 5
Events::fire(EventKeys::DISCONNECTION_EVENT, payload);

通知:

shared_ptr<PayloadObject<int>> number = dynamic_pointer_cast<PayloadObject<int>>(payload[0]);
int id = number.get()->obj; //payload[0] = int - 5

最佳答案

一种简单的方法是为 Payload 对象提供一个公共(public)基础或公共(public)接口(interface)。因此它们不是模板类。

struct Payload {
virtual ~Payload() = default;
virtual std::string foo() const;
virtual std::string bar() const;
};

另一种方法是对负载对象使用变体类型:

using Message_t = boost::variant<A, B, C>;

然后让 AEventListener 采用 Message_t 类型,这样它就不需要成员函数是模板。

class AEventListener
{
public:
virtual ~AEventListener();

virtual void notify(std::vector<Message_t> payload) = 0;
};

在 C++17 中,您可以为此使用 std::variant 而不是 boost。

另一种方法是跳过使用变体,而只是让 Listener 必须实现三个不同的函数,每种函数一个:

class AEventListener
{
public:
virtual ~AEventListener();

virtual void notifyA(A payload) = 0;
virtual void notifyB(B payload) = 0;
virtual void notifyC(C payload) = 0;
};

更一般地说,在 C++ 中很难提出“可以用任何特定类型的参数调用的函数对象”这样的概念。这部分是因为...它不是很有用,您可以对任何类型的数据做很多事情,您可以对任何类型的数据进行任何假设。

因此,我建议您仔细考虑改进您的事件监听器概念,并更具体地说明这种类型的对象实际上应该被要求做什么。

关于c++ - 在虚拟成员函数上使用模板的替代方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48601888/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com