A function is required to send messages, given a message type and a data structure of a type specific to the message type:
enum class MsgType
{
msgInt,
msgDouble,
msgString
};
template < some template here >
void sendMessage(MsgType type, T value);
I expect to call this function in the following way:
sendMessage( MsgType::msgInt, 42 );
sendMessage( MsgType::msgString, "Answer to the life, etc,etc.");
//sendMessage( MsgType::msgDouble, "Should not compile");
//sendMessage<MsgType::msgString>( "That is easy!" );
How could I implement the previously described template function specialization?
Note: If possible, with C++11, but C++14 is also acceptable.
EDITED:
The current implementation, which only accept the MsgType as template parameter (not as function parameter).
template<MsgType Id, typename T>
void sendMessage(T data);
template<>void sendMesssage<MsgType::msgNumCar, int>( int data ){ //... }
template<>void sendMesssage<MsgType::msgInt, int>( int data ){ //... }
template<>void sendMesssage<MsgType::msgString, string>( string data ){ //... }
// A call
sendMessage<MsgType::msgNumCar>( 42 );
Templates can have constant parameters which are known in compile-time. You could do the following:
enum MsgType {
msgInt,
msgDouble,
msgString
};
template<int>
struct Message { };
template<>
struct Message<MsgType::msgInt> {
static void send(int value) { cout << "int: " << value; }
};
template<>
struct Message<MsgType::msgDouble> {
static void send(double value) { cout << "double: " << value; }
};
template<>
struct Message<MsgType::msgString> {
static void send(const char* value) { cout << "string: " << value; }
};
And invoke it:
Message<MsgType::msgInt>::send(5);
Message<MsgType::msgDouble>::send(3.14);
Message<MsgType::msgString>::send("hello");
// will not compile
//Message<MsgType::msgDouble>::send("should not compile");
notice that the template parameter must be a constant (i.e. known at compile time). Which means that the following code won't compile:
int type = MsgType::msgInt;
Message<type>::send(123);
But, why won't you just create 3 overloads for sendMessage?
Instead of validating that the user passes the correct message type enum value into the send function, prevent it entirely with some traits:
#include <iostream>
enum class MsgType
{
msgInt,
msgDouble,
msgString
};
template <typename T>
struct MsgTypeOf;
template <>
struct MsgTypeOf<int>
{
static MsgType msg_type;
};
template <>
struct MsgTypeOf<double>
{
static MsgType msg_type;
};
template <>
struct MsgTypeOf<const char*>
{
static MsgType msg_type;
};
MsgType MsgTypeOf<int>::msg_type = MsgType::msgInt;
MsgType MsgTypeOf<double>::msg_type = MsgType::msgDouble;
MsgType MsgTypeOf<const char*>::msg_type = MsgType::msgString;
template <typename T>
int sendMessage(T value)
{
return static_cast<int>(MsgTypeOf<T>::msg_type);
}
int main()
{
std::cout << sendMessage(42) << std::endl;
std::cout << sendMessage("Answer to the life, etc,etc.") << std::endl;
std::cout << sendMessage(42.42) << std::endl;
}
Output: 0 2 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With