So, I have json file which has some parameters defining the name, value and type.
for e.g.,
{ name: "something", type: "uint32_t", value: 12 }
and I am creating struct mapping of this json parameter, it looks like
enum some_enum{en_int8, en_int16, ....};
struct{
std::string name; // Name of parameter
some_enum type; // type of parameter
union{
uint8_t var1;
uint16_t var2;
..... //all other requried types
}
}
As I don't know about the type of parameter coming from file, I am creating this union for storing value and using enum to access the specified value.
I think this is c-style way to do it.
So, I want to ask, is there any alternative way, rather than of using union for creating mapping like this in C /Modern C . Thank you in advance.
CodePudding user response:
You can use std::variant
but it is available and referenced officially from C 17. There is an alternative: Boost.Variant. As it is explained here: Boost Variant essentially a Union in c/c ? it provides a replacement for the generic C union in Boost
library, but the underlying code does not implement the same behaviour, preferring aligned storage. Thus, it depends if you are constrained with strictly the same behaviour as a generic C union, or not. However, Boost.Variant
requires a few additional efforts for templatizing your code, and/or writing functors to handle non-trivial argument types.
CodePudding user response:
What you are trying to do seems to be a serialization task. You can write your own code for doing that, but there are several libraries what you can use instead: Oops (https://bitbucket.org/barczpe/oops), boost serialization (https://www.boost.org/doc/libs/1_80_0/libs/serialization/doc/index.html), or Cereal.
CodePudding user response:
Based on what you have described in the Q, I think you do not need to use union if you go for modern C features like std::any
. So, I propose to use std::any
like this instead of std::variant
:
struct Param
{
std::string name; // Name of the parameter
std::any value; // type and value of the parameter
}
and for using this struct:
Param pi{"pi", std::make_any<double>(3.1415)};
In this case, the value
member of your struct stores both your type and the value of the parameter.
Note: std::any
is available since C 17. If you cannot migrate to C 17, you can use boost::any instead.