views:

78

answers:

3

I know vector< bool > is "evil", and dynamic_bitset is preferred (bitset is not suitable) but I am using C++ Builder 6 and I don't really want to pursue the Boost route for such an old version. I tried :

int RecordLen = 1;
int NoBits = 8;
std::ofstream Binary( FileNameBinary );
vector< bool > CaseBits( NoBits, 0 );
Binary.write( ( const char * ) & CaseBits[ 0 ], RecordLen);

but the results are incorrect. I suspect that the implementation may mean this is a stupid thing to try, but I don't know.

+1  A: 

Operator[] for vector <bool> doesn't return a reference (because bits are not addressable), so taking the return value's address is going to be fraught with problems. Have you considered std::deque <bool>?

anon
It's the "bitness" I want, not the "boolness". Your answer confirms my suspicions, I'll probably use a vector of char. Thanks.
Alex Strickland
A: 

the bool vector specialization does not return a reference to bool.

see here, bottom of the page.

f4
Actually, even if it did, it would be a reference to a bool[], i.e. with one bit per sizeof(bool) bytes - not the intended goal.
MSalters
A: 

It's too late for me to decide how compliant this is, but it works for me: give the bitvector a custom allocator to alias the bits to your own buffer.

Can someone weigh in with whether the rebound allocator inside the vector is required to be copy-constructed from the one passed in? Works on GCC 4.2.1. I seem to recall that the functionality is required for C++0x, and since it's not incompatible with anything in C++03 and is generally useful, support may already be widespread.

Of course, it's implementation-defined whether bits are stored forwards or backwards or left- or right-justified inside whatever storage vector<bool> uses, so take great care.

#include <vector>
#include <iostream>
#include <iomanip>
using namespace std;

template< class T >
struct my_alloc : allocator<T> {
        template< class U > struct rebind {
                typedef my_alloc<U> other;
        };
        template< class U >
        my_alloc( my_alloc<U> const &o ) {
                buf = o.buf;
        }
        my_alloc( void *b ) { buf = b; }
         // noncompliant with C++03: no default constructor
        T *allocate( size_t, const void *hint=0 ) {
                return static_cast< T* >( buf );
        }
        void deallocate( T*, size_t ) { }
        void *buf;
};

int main() {
    unsigned long buf[ 2 ];
    vector<bool, my_alloc<bool> > blah( 128, false, my_alloc<bool>( buf ) );
    blah[3] = true;
    blah[100] = true;
    cerr << hex << setw(16) << buf[0] << " " << setw(16) << buf[1] << endl;
}
Potatoswatter
Isn't one of the features of a vector (even a bit vector) that it should grow dynamically?
anon
@Neil: Not at 4 am. Seriously, with a little elbow grease and the assumption that only one (or two) blocks will be allocated at a time, you could adjust this and pull it off about as well.
Potatoswatter