Reputation: 322
In C++, suppose I have a messaging system that wraps messages in a generic struct:
template<typename T>
struct Message
{
std::string Name;
T Data;
};
I also have an interface that includes functions that need to use the purely generic version of this struct:
class Interface
{
public:
virtual ~Interface() { }
virtual void Receive(Message& message) = 0;
virtual Message Send() = 0;
};
However, Message
no longer names a type; things like Message<float>
and Message<std::string>
name types. Since the classes that will be implementing Interface
will want to catch different Message
, I can't just define a specific type.
The only way I can think to fix this is to rip out the template and using inheritance, but then I'd have littered throughout my code things like IntMessage
and BoolMessage
, which looks extraordinarily ugly. Any thoughts on how I can do this the way I want?
Upvotes: 3
Views: 2034
Reputation: 208353
A simple approach is to split the Message
type into a hierarchy:
struct MessageBase {
std::string Name;
};
template<typename T>
struct Message : MessageBase
{
T Data;
};
Then you can just pass MessageBase&
through interfaces.
[The previous won't work. The function will be able to accept any MessageBase&
object, but Receive
seems to be about storing in the argument a message for which the type is unknown a compile time. Although if you don't mind dynamic allocations you could have a Message
that holds the name and a pointer to a MessageBase
and then different implementations of MessageImpl
(the template above)]
Another common approach is to add all possible messages to an union and pass the union around.
Upvotes: 2
Reputation: 10418
Why don't you define your interface as a template?
template<typename T>
class Interface
{
public:
virtual ~Interface() { }
virtual void Receive(Message<T>& message) = 0;
virtual Message<T> Send() = 0;
};
Upvotes: 1