Home > Mobile >  Is there any alternative of using union in C , if data type of variable is not specified
Is there any alternative of using union in C , if data type of variable is not specified

Time:09-06

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.

  • Related