Randomizing all class variables in constructor c++ I'm playing around with making random items and decided to implement the following structure.

#include &lt;stdlib.h&gt; //uints 
#include &lt;limits&gt;
#include &lt;random&gt;
#include &lt;iostream&gt;

class RandomItem {
private:
    struct _physical_properties { uint16_t length; uint16_t width; uint16_t sqew; uint16_t weight; };
    struct _color { uint8_t r; uint8_t g; uint8_t b; uint8_t a;};
    //etc
public:
    _physical_properties physical;
    _color main_color;
    _color secondary_color;
    uint16_t durability;
    uint32_t type;

    RandomItem() = default;
    RandomItem(uint32_t _type) {
        union thing {
            RandomItem item;
            uint8_t buf[sizeof(RandomItem) / sizeof(uint8_t) ];
        };
        thing bad{};
        std::random_device dev;
        std::mt19937 gen(dev());
        std::uniform_int_distribution&lt;&gt; dist(0, std::numeric_limits&lt;uint8_t&gt;::max()); 
        for (auto&amp; b : bad.buf) {
            b = static_cast&lt;uint8_t&gt;(dist(gen));
        }
        *this = bad.item;
        this-&gt;type = _type;
    }
};

int main() {
    RandomItem a(1);
    RandomItem b(2);
    std::cout &lt;&lt; "item type: " &lt;&lt; a.type &lt;&lt; " Some values: " &lt;&lt; (int)a.physical.length &lt;&lt; ", " &lt;&lt; a.durability &lt;&lt; std::endl;
    std::cout &lt;&lt; "item type: " &lt;&lt; b.type &lt;&lt; " Some values: " &lt;&lt; (int)b.physical.length &lt;&lt; ", " &lt;&lt; b.durability &lt;&lt; std::endl;
    return 0;
}


(edited slightly to post here in a more minimal form...using iostream instead of fmt sticking in one file etc)

seeing as how:


The total number of properties in the class can increase and have (potentially) different types
I don't particularly feel like


prop1 = dist(gen);
prop2 = dist(gen);
prop3 = dist(gen);
//etc


is very scalable...

I wrote the displayed constructor and that's specifically what I'm asking for feedback on (rest of the dummy class is just for the example)

It uses a union between the item and a buffer and fills that buffer with random values then sets the current object equal to the unionized item.

This feels hacky however might be better than alternatives (individually setting each variable manually or the other end of the gross hack scale making a macro that expands to setting each variable)

Are there any major gotchas with doing this?

Am I relying on undefined behavior and or will this style of code introduce bugs down the line? (as far as I can see it doesn't quite matter what the endianness of the computer is 'cause the value is random)

Is this the best way to implement my goal? (set all the variables and nested variables to random values on construction).

I'm posting here instead of StackOverflow because it appears to work (compiles and  and I assume any answers would just be opinion-based.
I'm not working with other people and for now, I'm just experimenting with things. (this isn't being used in a project but I might add it into one in the future.).

Is it "better" to make the class nothing but POD without a constructor and then implement a function that does pretty much the same code and return the constructed item? (something like)

Item&amp; randomItem(uint32_t type){
    union thing{
        Item item;
    //snip 
    ...
    return item;
} 


To avoid the hacky *this = item; code (smell?)

Of course, if I was actually writing a game or similar program that implemented a class of random variables I'd probably have some constraints for what the random values for different types of items could be. (For example, length/width might be a distribution between (300-1000) instead of (0-maxValueOfType) so maybe this is just a contrived example. However, if anyone has any feedback on the rest of the concept I'd be interested.
In theory, I think this is allowed because your Items are trivial types, but this is pretty ugly.

I think you can do better using std::array.

struct _color { uint8_t r; uint8_t g; uint8_t b; uint8_t a;};


could be

struct _color {
    auto&amp; r() { return data[0]; }
    // etc
    void randomize() { /* fill data with random stuff */ }
    private:
        std::array&lt;uint8_t, 4&gt; data;
};




P.S. I think you will find that uniformly randomly setting r, g, b, and a doesn't look random to humans.



P.P.S.  There is a proposal to add something like this:

_color color;
for... (auto&amp; component : std::meta::members(color)) {
    // do stuff with component
}


I haven't followed this proposal but it sounds like it would help here.