Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Initializing member references to dummy member variables

Reply
Thread Tools

Initializing member references to dummy member variables

 
 
darylew@gmail.com
Guest
Posts: n/a
 
      08-20-2013
On Monday, August 19, 2013 2:14:18 PM UTC-4, James Kanze wrote:
> On Sunday, 18 August 2013 09:10:27 UTC+1, (E-Mail Removed) wrote:
>
> > For your main problem: you need to use either an integer or a string. And
> > neither both together nor none at all; always exactly one. If you're using
> > C++11, this is a job for a union.
> >
> > // Not tested
> > class Handle {
> > union MyData {
> > int i;
> > std::string s;
> > MyData( int i = 0 ) : i{ i } {}
> > MyData( std::string const &s ) : s{ s } {}
> > MyData( std::string &&s ) : s{ std::move(s) } {}
> > } data;
> > bool useStr;

>
> > public:
> > Handle( int i ) : data{ i }, useStr{ false } {}
> > Handle( std::string const &s ) : data{ s }, useStr{ true } {}
> > Handle( std::string &&s ) : data{ std::move(s) }, useStr{ true } {}

>
> > Handle( Handle const &that );
> > Handle( Handle &&that );
> > ~Handle();

>
> > void swap( Handle &that );

>
> > Handle & operator =( Handle that )
> > { this->swap(that); }
> > //...
> > };

>
> > In previous versions of C++, a union could not have a member
> > if any of its special member functions were non-trivial. All
> > of std::string's s.m.f.s are non-trivial, so you have to use
> > one of the aforementioned solutions if you're using a pre-11
> > compiler. For C++11, non-trivial types can be in a union, but
> > each special member function is deleted (i.e. cancelled)
> > unless all its members' versions of that s.m.f. is trivial.
> > Handle will start off with NO s.m.f.s available until we add
> > them in manually.

>
> What does the destructor of the union do in this case? If the
> last field used was the string, then it needs destruction; if
> the last field used was the int, then destruction of the string
> element would be undefined behavior. According to the standard,
> if and non-static data member of the union has a non-trival
> destructor, the corresponding member function of the union must
> be user-provided or it will be implicitly deleted for the union.
> Implicitly deleting a destructor means that the only thing you
> can do with the resulting union is to allocate it dynamically,
> and never delete it.


* std::string has a non-trivial destructor
* the automatically-created version of MyData::~MyData is deleted
* there is no manual destructor for MyData
* so MyData is indestructible
* which makes Handle::~Handle deleted by default
* but there is a manually-created version of outer destructor.
* so Handle CAN be used in destructible contexts
(I think. However, this facility would be useless if it that
assertion isn't true.)

> To use the union in a class, you need to provide a user defined
> destructor. But don't ask me what it should do. It will have
> to use an explicit destructor call to destruct the string
> member, but only if the string member was the active member
> (which is information it doesn't have).


You didn't notice that I did write a manual destructor for Handle?
In fact, I wrote justifications for all my steps. Handle has the tag
for int vs. string. (It can't be in Handle::MyData.)

> In fact, what he needs isn't a union, but a variant (from
> Boost, or hand written, if you can't use Boost); a discriminate
> union, if you prefer.


That is what I wrote; Handle is a discriminated union wrapping the
plain union MyData. The variant from Boost, or hand-written code,
would do something similar to what I did.

> For the rest: VC++ doesn't support this feature of C++11 yet,
> so portability would be limited. With g++ 4.7.2, it does work
> if I define the union as:


Which feature didn't work? Did you try to compile my (untested)
code?

> union U
> {
> int i;
> std::string s;
> U() : i() {}
> ~U() {}
> };
>
> and do everything with placement new/explicit delete on U::i or
> U::s (exactly as you would if you were implementing Variant
> yourself). Globally, this feature does make the implementation
> of Variant somewhat cleaner---you loose a lot of
> reinterpret_cast, and additional members necessary to
> (hopefully) ensure alignment. But it probably shouldn't appear
> elsewhere; it's too tricky to get right.


Yes on that last sentence.

Daryle W.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dummy, underscore and unused local variables Tim Johnson Python 1 06-13-2011 04:02 PM
Put variables into member variables or function variables? tjumail@gmail.com C++ 9 03-23-2008 04:03 PM
Initializing static reference (non-POD) member variables Grey Alien C++ 8 07-24-2007 06:07 PM
Initializing member variables that are struts 2b|!2b==? C++ 5 05-02-2007 10:08 AM
how to understand references to variables and references to constants are distinguished? baumann.Pan@gmail.com C++ 3 11-10-2004 04:16 AM



Advertisments