Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::optional<> in a union?

I have an optional POD struct that will be contained inside a union.
boost::optional<> holds its type by value, so I thought this could work:

union helper
{
    int foo;
    struct 
    {
        char basic_info;
        struct details {
            //...
        };

        boost::optional<details> extended_info;
    } bar;
    //  ...
};

helper x = make_bar();

if( x.bar.extended_info )
{
    // use x.bar.extended_info->elements
}

but VS2008 complained that my bar struct now had a copy constructor due to the boost::optional<details> element.

As a replacement, I've added a boolean flag to indicate whether the optional parameter is valid, but it's clunky:

union helper
{
    int foo;
    struct 
    {
        char basic;
        struct details {
            bool valid;
            //...
        } extended;
    } bar;
    //  ...
};

I considered implementing details::operator bool() to return the details::valid variable, but that's obscure and a disservice to humanity.
boost::optional<> clearly documents the syntax and intent and doesn't require detective work.

Finally, the helper union needs to be POD, so I can't do any dynamic allocation - otherwise I would use a pointer.

Any suggestions for something syntactically similar to boost::optional<> that's usable in a union?

like image 864
mskfisher Avatar asked Jan 12 '11 20:01

mskfisher


People also ask

What is boost :: optional?

Optional provides the class boost::optional , which can be used for optional return values. These are return values from functions that may not always return a result. Example 21.1 illustrates how optional return values are usually implemented without Boost.

Does STD optional allocate?

optional is required to not use dynamic allocation. If an optional contains a value, the value is guaranteed to be allocated as part of the optional object footprint, i.e. no dynamic memory allocation ever takes place.


1 Answers

You can not use non-POD types as fields in union. Use boost::variant or something like it in C++ instead of union. Leave union only for compatibility with modules written in C.

like image 175
Öö Tiib Avatar answered Sep 24 '22 02:09

Öö Tiib