gpt4 book ai didi

c++ - 使用元编程进行消息队列管理

转载 作者:行者123 更新时间:2023-11-30 04:19:08 25 4
gpt4 key购买 nike

我正在用 C++ 实现一个通信机制,它是用消息队列和消息类设计的。也就是说,一个抽象父类 Message 和类 Communication,其中存在一个方法 Communication::send(Message&)Communication 类将消息发送到适当的消息队列 message_queue,这由消息的类型决定。(也就是说,对于 Msg1,它发送到队列 Queue_Msg1Msg2 发送到 Queue_Msg2)每个消息类型都将创建为 Message 的派生类。

主要是,我对自动创建队列很感兴趣。也就是说,如果我决定添加一个新的消息类型类 newMsg,添加消息队列 Queue_newMsg 的过程将不需要更改 Communication< 中的代码 类,例如为每种消息类型创建队列的代码。

因为这可以在编译时完成(在编译时,所有派生的消息类都是已知的,因此需要消息队列),我试图想出一些元编程解决方案,但没有成功找到这样的。

使用一些已知的 MPL,例如 boost/mpl,我怎样才能实现上述目标?

最佳答案

将类型打包到列表中:

template<typename... Ts>
struct type_list {};

使用该列表和参数包解包创建一个 std::array队列。如果您希望队列本身具有特定类型,则它们需要位于 tuple 中。 .

上面的列表暗示了索引和类型之间的双射。让每种类型的实例返回索引,您可以使用它来获取队列(在数组中,简单 - 在 tuple 中,需要更多工作)。

index_of traits 类,查找类型的索引 Ttype_list<Ts...> :

template<typename T, typename list, typename=void>
struct index_of {};

template<typename T, typename T0, typename... Ts>
struct index_of<T, type_list<T0, Ts...>,
typename std::enable_if<std::is_same<T, T0>::value>::type
> : std::integral_constant<size_t, 0>
{};

template<typename T, typename T0, typename... Ts>
struct index_of<T, type_list<T0, Ts...>,
typename std::enable_if<!std::is_same<T, T0>::value>::type
> : std::integral_constant<size_t,
index_of<T, type_list<Ts...>>::value+1>
{};

可能实现一个基于 CRTP 的“消息助手”,它同时实现 GetTypeIndex并确保您的类型在中央消息列表中。

这需要 C++11,在 C++03 中它更难,也更受限制。 C++11 编译器也可以处理 100 种类型,而无需进行太多额外的模板元编程(使用严格的元编程,1000 种或更多,至少在理论上是这样),而 C++03 编译器即使具有强大的元编程库也可能仅限于10 种类型。

请注意,这种方法的一个优点是,理论上,您可以完全取消抽象父类,或者至少可以取消 sendMessage( message const& m )。接口(interface)(为什么要允许人们发送抽象消息?)。您可能只被允许发送实际的具体消息类型。这又需要一些更多的工作(您创建使用 CRTP 获取队列的包扩展继承树)。

struct MessageBase {
virtual size_t GetTypeIndex() const = 0;
};
template<typename D, typename List>
struct MessageHelper: public MessageBase {
static_assert( std::is_base_of< MessageHelper<D,List>, D >::value, "MessageHelper<D> must be inherited from by D" );
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D const*>(this); }
virtual size_t GetTypeIndex() const final override {
return index_of<D,List>::value;
}
};

struct A_Queue {
std::deque< std::unique_ptr<MessageBase> > data;
};

template<typename type_list>
struct MessageQueues;

template<typename... Ts>
struct MessageQueues<type_list<Ts...>> {
std::array< A_Queue, sizeof...(Ts) > queues;
void Enqueue( std::unique_ptr<MessageBase> msg ) {
size_t index = msg->GetTypeIndex();
queues[ index ].data.push-back( std::move(msg) );
}
};

对于一个非常粗略的实现草案。

关于c++ - 使用元编程进行消息队列管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16043622/

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