Is it possible to initialize a union in a mem initializer?

I am surprised that this does not work:

union DlDatum { float mFloat; s32 mInteger; }; class DlDbE { public: DlDbE( float f ) : mData.mFloat( f ) {}; private: DlDatum mData; }; 

Is there a way to initialize the union in the mem-initializer list of the C ++ constructor?

Update: The answer is to create constructors for the union. I did not know that this could be done. Here is what I did:

 union DlDatum { float mFloat; s32 mInteger; bool mBoolean; u32 mSymbol; u32 mObjIdx; DlDatum( ) : mInteger( 0 ) {} DlDatum( float f ) : mFloat( f ) {} DlDatum( s32 i ) : mInteger( i ) {} DlDatum( bool b ) : mBoolean( b ) {} DlDatum( u32 s ) : mSymbol( s ) {} // this ctor should work for objIdx also }; class DlDbE { public: DlDbE() {} DlDbE( float f ) : mData( f ) {} DlDbE( u32 i ) : mData( i ) {} DlDbE( bool b ) : mData( b ) {} ...etc.. private: DlDatum mData; }; 
+6
source share
3 answers

Like any other member, if you want to build a union, you will need to give the union a constructor and call it.

+11
source

In C ++ 03, and before you are limited to writing a constructor for your union.

In C ++ 11, unified initialization extends aggregate initialization syntax for constructor initializer lists. That means the old old syntax syntax is kind of

 DlDatum d = { 3.0 }; 

which we all know and love with C and which initializes the first member of the union, can now also be used in constructor initializer lists, as well as

 union DlDatum { float mFloat; s32 mInteger; }; class DlDbE { public: DlDbE( float f ) : mData{f} {} private: DlDatum mData; }; 

This function allows you to "target" the first non-static member of a union to initialize. If you need something more flexible, then it will return to writing constructors.

+10
source

@AndreyT gives an excellent answer, which I will cover in detail with a little practical advice.

I tend to use alliances to get easy access to the value of a bitmap without the tedious and ugly bitwise and / bitwise or. I think this is a fairly common practice.

One of the methods that I used for a while to make the process even easier is if I work with a raster image of less than 32 bits in size, I declare it as an unnamed structure inside the union with a member of the DWORD companion. For instance:

 union UNICODECONTROL{ DWORD dwAccessor; struct{ unsigned unicode_01 : 1; unsigned unicode_02 : 1; unsigned unicode_03 : 1; unsigned unicode_04 : 1; unsigned unicode_05 : 1; unsigned unicode_06 : 1; unsigned unicode_07 : 1; unsigned unicode_08 : 1; unsigned unicode_09 : 1; unsigned unicode_10 : 1; }; }; 

With this in place, it will work as an "accessor" function. If you want to set the values, you can do it at a time by assigning a number with the corresponding bitmap to this "accessory". You want to reset them - also a piece of cake. This works especially well with the Windows registry. To preserve the value of the merged bitmap, all you have to do is just write the DWORD to the registry! Getting it later for reinitialization is equally simple.

DWORD is one of the native registry types, and you don’t need to bother with static castings or write manual conversion functions. If you have a longer bitmap than 32 bits, you can declare an integer of 64 bits, and it will work just as well as the whole, and equally with the registry, since QUADWORD is also native.

If this applies directly to what @AndreyT mentions - if you need a convenient initialization of a class data element in my union-bitmap / DWORD format, all you have to do is - as in the example - make sure that "accessor" '- The first value declared in the union. Then you can list it directly using the new C ++ 11 '{} schema. No need for some weird connection constructors!

Warning. If individual bitmaps live inside, the DWORD access device will depend on the alignment setting for your structures. This is installed at the compiler level or with the __declspec(align(#)) instruction in MSVC ++ and similar syntax in other compilers.

Lastly, an update extracted from trying these ideas in several different scenarios recently. Despite the fact that in C ++ 11 it is explicitly stated that it is legal to initialize the union of its first variable, as described above, MSVC ++ seems to ignore this standard - or "does not implement" it as a state of exit from the compiler. Therefore, if you use the Microsoft compiler, you will have to implement a messy constructor for your union if you want to initialize it. Shame, but, apparently, compliance with the C ++ 11 standard will improve in the following service packs to VS2013 and with the next iteration of 2014 of the entire IDE.

+1
source

All Articles