I have a Message
structure that I am using with a message bus, and I'd like to send data with messages. The problem is that the data will vary in type; maybe for one message I'll just want to send one int, but for another I'll want to send several ints, a string, maybe even a pointer to an object for example. I could do something like this:
struct Message {
std::map<int, int> intPayload;
std::map<int, std::string> strPayload;
short id;
};
But not only is this ugly and unclean, and probably wastes space, but that doesn't account for if I want to pass a relatively exotic data type like a pointer to an instance of a class for example. What should I be using for this?
There are many ways to do this. Here's an example with C++17's std::variant
:
std::vector<std::variant<int, std::string>> vec1;
vec1.emplace_back(1);
vec1.emplace_back("hello"s);
doSomethingWithInt( std::get<int>(vec1[0]) );
doSomethingWithString( std::get<std::string>(vec1[1]) );
vec1
is a list of element that are either int
or std::string
.
You can also use a static visitor:
std::vector<std::variant<int, std::string>> vec2;
// ...
for(auto&& variant : vec1) {
variant.visit([](auto value){
using t = decltype(value);
if constexpr (std::is_same_v<t, int>) {
std::cout << "value is a int!" << std::endl;
} else if constexpr (std::is_same_v<t, std::string>) {
std::cout << "value is a string!" << std::endl;
}
});
}