static const in struct

D

dj

Perhaps this question should be in the standard c newsgroup, but i hope
somebody answers it here. Anyway, I came across this situation in an
otherwise c++ code.

I need a struct that works like some sort of a flag set. The flag mask
is a single long, while the meaning of individual flags is given by
static const members of the same struct:

struct flag_set {
long flags;
static const long FLAG1_BIT = 0x1;
static const long FLAG2_BIT = 0x2;
...
static const long FLAGN_BIT = 1 << N-1;
}

Of course the consts have meaningful names in my code, so i can check
for some condition like this:

flag_set fs;
....
if (fs & flag_set::FLAGX_BIT) {
do something;
}

I suppose this is one of many possible ways to approach the problem but
i am not sure if it is the best one as well. The storage should not be
the problem, even with many flag_sets floating around, because static
members don't use additional space (i am pretty sure about that).
However, i have not seen much code written this way and would like to
know if someone knows for a better way to do it, that is for some reason
why the upper solution is not good.

If nothing else, this is a question of proper programming style that i
still need to work on. All answers without "this is a stupid question"
in them are much appreciated.
 
M

mlimber

dj said:
Perhaps this question should be in the standard c newsgroup, but i hope
somebody answers it here. Anyway, I came across this situation in an
otherwise c++ code.

I need a struct that works like some sort of a flag set. The flag mask
is a single long, while the meaning of individual flags is given by
static const members of the same struct:

struct flag_set {
long flags;
static const long FLAG1_BIT = 0x1;
static const long FLAG2_BIT = 0x2;
...
static const long FLAGN_BIT = 1 << N-1;
}

Of course the consts have meaningful names in my code, so i can check
for some condition like this:

flag_set fs;
...
if (fs & flag_set::FLAGX_BIT) {
do something;
}

I suppose this is one of many possible ways to approach the problem but
i am not sure if it is the best one as well. The storage should not be
the problem, even with many flag_sets floating around, because static
members don't use additional space (i am pretty sure about that).
However, i have not seen much code written this way and would like to
know if someone knows for a better way to do it, that is for some reason
why the upper solution is not good.

If nothing else, this is a question of proper programming style that i
still need to work on. All answers without "this is a stupid question"
in them are much appreciated.

There's nothing innately wrong with the code. I would tend to prefer
using an enum within the class rather than static constants just
because it is less typing. You might also consider abstracting the bit
twiddling by hiding the enum and providing inline member functions like
this:

class FlagSet
{
private:
long flags_;

enum
{
FLAG_1 = 1,
FLAG_2 = 2,
// ...
};
public:
bool IsFlag1Set() const { return flags_ & FLAG_1; }

FlagSet& SetFlag1()
{
flags_ |= FLAG_1;
return *this;
}

FlagSet& ClearFlag1()
{
flags_ &= ~FLAG_1;
return *this;
}

// ...
};

void Foo( FlagSet& fs )
{
if( fs.IsFlag1Set() )
{
fs.SetFlag2().SetFlag5().ClearFlag7();
}
}

The setting and clearing business in the if-statement's body uses
method chaining (cf.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18).

Cheers! --M
 
L

Lyell Haynes

suppose this is one of many possible ways to approach the problem but
How about an enum?

struct flag_set {
long flags;
enum FLAG {
FLAG1 = 1,
FLAG2 = 1 << 1,
FLAG4 = 1 << 2,
...,
FLAGN = 1 << sizeof(long)-1
};
};

The usage would be the same:

flag_set fs;
fs.flags = flag_set::FLAG1 | flag_set::FLAG2 | flag_set::FLAG4;

if (if (fs.flags & flag_set::FLAG4) {
// do something
}
 
S

shimons

I can't see anything wrong with your approach or with apporach which
uses enums for flag mask values. These are valid approaches, which
don't take use of already made class that handles flags operations.
Thus, my suggestion would be to use STL bitset class.

#include <bitset>
#include <iostream>

void main()
{
std::bitset<20> b;

b.set(5); // turn on bit number 5

if (b.test(5))
{
// do something
}

std::cout << b[5] << std::endl;
}

I showed only small use of it. There is much more to it. For instance,
you could flip bits in certain places using "flip" method, check if
there's any of the flags turned on with "any" method,
ie: if (b.any()) {...} and much more.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,107
Latest member
Vinay Kumar Nevatia_
Top