   Bypassing the "vectorbool" specialization
  As those of you well versed in the STL know, "vector<bool>" is actually a specilization of the vector container that uses a bitfield to store the booleans. This was an experiment (and one that failed horribly) but sadly was never removed from the specifications.Now, I was wondering if anyone here knew how to bypass the "vector<bool>" specialization so "vector<bool>" actually stores whole booleans as opposed to using a bitfield. So far I have found 2 ways of doing this:1) Using "vector<char>" instead.The pros is that it's very easy to do. The cons is that "vector<char>" doesn't exactly scream "I'm storing booleans". It's also not platform-indepandant as the bool type isn't always 8 bits.2) Using a custom allocator, as mentioned here, such as "vector<bool, myallocator>"The pros: it works. The cons: I know nothing of custom allocators.My goal is to create a typedef named "vector_bool" which is, yes you guessed it, a vector that stores bools. It will obviously be stored in a different namespace to vector as touching the "std" namespace is A Bad Idea. If someone could share with me a custom allocator that basically minics the default allocator (I'm guessing that copying and pasting the code for the default allocating and giving it a new name would work) I would appreciate it, or any other ideas on how to get around the specialization.Thanks in advance   
  I have never tried it, but I believe the following will work#include <vector>struct s_bool{bool data;s_bool(bool copy):data(copy){}bool& operator=(bool rhs){data = rhs;return data;}operator bool()const{return data;}};typedef std::vector<s_bool> vector_bool;And a simple test:#include <iostream>#include <ostream>vector_bool vec;int main(){vec.push_back( false ) ;vec.push_back( false ) ;vec.push_back( true ) ;for( std::vector<s_bool>::const_iterator iter = vec.begin();iter != vec.end();++iter){std::cout << *iter << std::endl;}for( std::vector<s_bool>::iterator iter = vec.begin();iter != vec.end();++iter){std::cout << (*iter = false) << std::endl;}for( std::vector<s_bool>::const_iterator iter = vec.begin();iter != vec.end();++iter){std::cout << *iter << std::endl;}return 0;}EDIT: I can't promise that it will be as efficient as std::vector<bool> though.   ;  vector<bool> works just fine in large-scale scientific applications.I'm not sure why anyone would refer to it as a mistake. It's fast, it's memory efficient, and it's extremely easy to use since it follows the STL's generic programming model perfectly.I think you answered your own question. vector<char> in combination with the bitwise operators would certainly give you the same memory optimization as the native vector<bool>. However, obtaining the speed optimization of the vector<bool> are slim to none, so it doesn't make sense to roll your own, so to speak.STL Tutorial and Reference Guide: C++ Programming with the Standard Template Library (2nd Edition) has a chapter on writing custom allocators. Great book to have all around.   ;  ok wow that's actually a pretty good idea o_O   ;  My preferred solution is to use a std::deque<bool> instead. As for 1), char isn't necessarily 8 bits either. As for 2), whoever suggested that was smoking something funny. std::vector<bool, allocator> will use the "optimization" no matter what allocator is passed.Consider uncommenting the lines in main() and see what happens:#include <vector>#include <deque>#include <limits>template <typename T> class MyAllocator; template <>class MyAllocator<void> {  public:    typedef  void * pointer;    typedef const void * const_pointer;    typedef void value_type;template <typename U>    struct rebind { typedef MyAllocator<U> other;    };    }; template <typename T>class MyAllocator {  public:    typedef size_t    size_type;    typedef ptrdiff_t difference_type;    typedef T *  pointer;    typedef const T * const_pointer;    typedef T &  reference;    typedef const T & const_reference;    typedef T    value_type;template <typename U>    struct rebind { typedef MyAllocator<U> other;    };MyAllocator() throw() {}    MyAllocator(const MyAllocator & other) throw() {}    ~MyAllocator() throw() {}pointer  address(reference x) const { return &x; }    const_pointer address(const_reference x) const { return &x; }pointer allocate(size_type n, MyAllocator<void>::const_pointer hint = 0) { void * ptr = malloc(n * sizeof(T)); if (!ptr) throw std::bad_alloc(); return static_cast<pointer>(ptr);    }    void deallocate(pointer p, size_type n) { free(p);    }size_type max_size(void) const throw() { return std::numeric_limits<size_type>::max();    }void construct(pointer p, const_reference val) { new (p) T(val); }    void destroy(pointer p) { p->~T(); }}; template <typename T>bool operator==(const MyAllocator<T> &, const MyAllocator<T> &) {  return true;} template <typename T>bool operator!=(const MyAllocator<T> &, const MyAllocator<T> &) {  return true;}int main(int, char **) {  //std::vector<bool, MyAllocator<bool> > bool_vec;  //std::vector<bool> bool_vec;  std::deque<bool> bool_vec;    bool & b = bool_vec[0];  };Quote:Original post by tabyvector<bool> works just fine in large-scale scientific applications.I'm not sure why anyone would refer to it as a mistake. It's fast, it's memory efficient, and it's extremely easy to use since it follows the STL's generic programming model perfectly.Except it doesn't follow all the rules for STL containers. If I wanted a static-sized bitfield I would use the one in STL or dynamic_bitset/field (can't remember the name) in boost if I needed a dynamic one. Specializing such a common container into a form that isn't usable in all the places where every other vector container are was very short-sighed by the standards comittee and one that still hasn't been rectified :/.   ;#include <vector>#include <boost/mpl/vector.hpp>#include <boost/mpl/equal_to.hpp>#include <boost/mpl/find_if.hpp>#include <boost/mpl/sizeof.hpp>#include <boost/mpl/deref.hpp>namespace stdfix{namespace detail{using namespace boost::mpl;typedef vector<unsigned char,unsigned short,unsigned int, unsigned long> type_list;typedef equal_to< sizeof_<_1>, sizeof_<bool> > has_same_size_as_bool;typedef find_if<type_list, has_same_size_as_bool>::type iter;}typedef ::boost::mpl::deref<detail::iter>::type bool_;typedef ::std::vector<bool_> vector_bool;}int main(){stdfix::vector_bool vec(25);vec.push_back(true);vec.push_back(true);vec.clear();}Of course, you lose the special treatment that bool values get (e.g. std::boolalpha and 0-1 coercion), but if all you want is a type that has the same size as bool does, that's how you can get it.Quote:Original post by tabyI'm not sure why anyone would refer to it as a mistake. It's fast, it's memory efficient, and it's extremely easy to use since it follows the STL's generic programming model perfectly.There are type system issues. Returning a convertible-to-bool isn't the same thing as returning a bool. The std::vector<bool> special case makes writing generic code that works on std::vector<T> a major hassle.   ;Quote:Original post by FrunyQuote:Original post by tabyI'm not sure why anyone would refer to it as a mistake. It's fast, it's memory efficient, and it's extremely easy to use since it follows the STL's generic programming model perfectly.There are type system issues. Returning a convertible-to-bool isn't the same thing as returning a bool. The std::vector<bool> special case makes writing generic code that works on std::vector<T> a major hassle.Exactly.  Namely, this trick can't be used if T could possibly be bool:c_style_function( &vector[0] , vector.size() );While C89 has no bool type, C99 does, as does C++, which can be used to write C style functions just fine.  Unless you're a smelly hermit, chances are you'll have to interface with such functions, written by others which you can't/shouldn't modify, and it is much easier if you can directly interact with them using the STL.  Having a specialization for bool which breaks the guarantees that allow this does not follow the STL's generic programming model at all.Having a seperate class which allows this (*cough* boost::dynamic_bitset *cough*) would be much saner.  Requiring bit packing in such an alternative would also mean you wouldn't be giving up guarantees which make programming easier for a mere dubious possibility of a performance increase.   ;  Fruny, I would rate you up but you're already at the top :).That code looks perfect, and I'm already using Boost for my current project (although I haven't delved into the MPL yet - still getting fully aquainted with all aspects of the STL).   ;  Thanks for the info. :)I see now that it doesn't follow the generic programming. My use of the vector< bool > was only through the [] operator, with everything pre-reserved/resized, like a static array. So, nothing as complex as you all described.I'll definitely keep all of this in mind. Again, much appreciated.   