I'm working on improving an in-house messaging library, designed to send messages internally within our applications, and to external consumers. A message consists of a MessageType (enum class) and some data (struct). Each MessageType:: corresponds to a particular data type (e.g., MessageType::TypeA will always contain Foo). However, multiple message types could use the same struct (e.g., MessageType::TypeM could also use Foo).
We have a class that can send messages. Our previous implementation of the message sender class defines a method for each type:
SendMessageTypeA(Foo data)
SendMessageTypeB(Bar data)
SendMessageTypeM(Foo data)
When there are lots of messages, this can result in a lot of code duplication (the method body is essentially the same, with the exception of the different parameter types).
I've implemented a new method:
template<typename structType>
void Send(MessageType msgType, const structType & messageData)
This single method can send any message, depending on the appropriate template parameter being provided.
The problem is that this new method does not enforce the relationship between MessageType and struct. For example, Send<Foo>(MessageType::TypeB, data) will compile, even though MessageType::TypeB should contain Bar. The mismatch will be detected at runtime, but I'd like to make it a compile time error.
I'm not sure how to achieve this. I've considered:
- Declaring all the 
SendMessageX()methods, and use them to callSend<MessageX>(). This does reduce the duplication, but I still have to create a new method every time a message is defined. - Attempting to use 
static_assertto catch the mismatch. I'm not sure how to mapMessageTypes to their desiredstruct. - I'm barking up the wrong tree
 
Aucun commentaire:
Enregistrer un commentaire