I want to explore how I can use std::any
instead of void * or such constructs for message passing. So I created an example code to test this - see below.
The use of std::any looks nice, but I want to switch through the types to check which type the std::any is. It might no be possible, and I know I can use a if/elseif... block instead, but it would be very nice if I can create a switch statement so that if I use this in real code with 10-20 different types it will be more readable.
#include <string>
#include <iostream>
#include <sstream>
#include <any>
#include <typeindex>
struct ints { int a{1}; int b{2}; };
struct strings { std::string a{"string1"}; std::string b{"string2"}; };
void send_msg(std::any item)
{
switch (item.type().hash_code()) // <------- HERE
{
case typeid(ints).hash_code(): // <------- HERE
std::cout << "ints" << std::endl;
break;
case typeid(strings).hash_code():
std::cout << "strings" << std::endl;
break;
default:
std::cout << "unknown type\n";
}
}
int main()
{
strings s;
send_msg(s);
ints i;
send_msg(i);
}
live example: https://godbolt.org/z/xPrMYM
I can't switch on the type_info returned by std::any::type, but I can switch on the hash_code()
of the type_info, but that is not a constexpr I hoped it was though!
so I also tried getting the address of the type info and a few other tricks that I could find. But no luck so far...
Is there such a way?
std::variant
andstd::visit
– Fucoidany
's type; you switch over the type of the message, and the handler for that message's type knows what type to cast theany
to. – Droverany
is just an unconstrainedvariant
, and if you're switching over types that suggests you want it to be constrained. – Depersonalizestruct myints : ints { };
and puts ` myints` in thestd::any
, then you won't recognize it, which violates the Liskov Substitution Principle. – Fortunestd::any
yet then! - I was reading that it can be used to replacevoid*
and such things - so I guess we can use eitherstd::any
orstd::variant
and the difference is a bit subtle... – Allardvoid*
if you know the correct type to cast it to. You can't "switch over types" with avoid*
, so what you're trying to do wouldn't work with avoid*
either. – Droverany
is meant to be used for these circumstances – Drovertype
field (that I am missing). So if I update my example to have a type field then it all makes more sense and I can swtich over thetype
enum/int thanks. This is probably as good an answer as I need so feel free to post that up – Allardtypeid
which evaluates at compile time. See the examples in the Readme – Fidelfidela