Boost logo

Boost :

From: Noah (noah_at_[hidden])
Date: 2004-09-11 18:55:46


> Jonathan Turkanis

> "Matthias Schabel" <boost_at_[hidden]> wrote:

> > Why give an explicit integer label to any of the values (except the
> > starting value)? It seems to me that the point of an enum declaration
> > is to guarantee unique values for each tag, but relying on having any
> > specific value correspond to a given tag is dangerous. I would write
> > it like this :
> >
> > enum
> > {
> > f_open = 0,
> > f_input_closed,
> > f_output_closed,
> > f_output_buffered
> > };
>
> If all you want is unique values, this is fine. But in the cases I was
> describing (from iostreams and regex) the goal is to define a set of
> constants
> which can serve as bit flags. The easiest way to do this is for each
> constant to
> have twice the value of the previous constant -- starting at 1 instead of
> 0, of
> course ;-)
>
> Thus the proliferation of <<'s

I hate having the shift value represent the flag - it's too easy to believe
that you're just supposed to pass the value as is. Then you have to go
lookup whether the value is a shift or the flag value itself. It's a
serious pain.

You could have the best of both worlds if you wrap the parameter up in a
class. Here's a brief sketch off the top of my head (so don't try to
compile and use it!):

template<typename E>
class BitFlag
{
        int flag;

public:
    BitFlag(E val)
        { flag = 1 << val; }
};

It makes the enum much easier to deal with since you can just simply put the
flags in a list and not worry about explicitly initializing each flag. You
can also add additional functionality. You could overload operators to
handle passing or masking multiple flags. You could also, through the use
of a traits class, validate flag combinations.

-- Noah


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk