Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to vector<bool>

As (hopefully) we all know, vector<bool> is totally broken and can't be treated as a C array. What is the best way to get this functionality? So far, the ideas I have thought of are:

  • Use a vector<char> instead, or
  • Use a wrapper class and have vector<bool_wrapper>

How do you guys handle this problem? I need the c_array() functionality.

As a side question, if I don't need the c_array() method, what is the best way to approach this problem if I need random access? Should I use a deque or something else?

Edit:

  • I do need dynamic sizing.
  • For those who don't know, vector<bool> is specialized so that each bool takes 1 bit. Thus you can't convert it to a C-style array.
  • I guess "wrapper" is a bit of a misnomer. I was thinking something like this:

Of course, then I have to read into a my_bool due to possible alignment issues :(

struct my_bool
{
    bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
like image 437
rlbond Avatar asked Mar 22 '09 00:03

rlbond


People also ask

Is vector bool deprecated?

There is a general consensus among the C++ Standard Committee and the Library Working Group that vector<bool> should be deprecated and subsequently removed from the standard library, while the functionality will be reintroduced under a different name.

Is Bitset faster than vector bool?

So it seems under these conditions, bitset is faster than vector when the code is optimized, while vector actually comes out on top by a (very) small margin when it's not.


3 Answers

Use std::deque if you don't need the array, yes.

Otherwise use an alternative vector that doesn't specialize on bool, such as the one in Boost Container.

like image 66
Daniel Earwicker Avatar answered Oct 07 '22 08:10

Daniel Earwicker


That's an interesting problem.

If you need what would have been a std::vector if it was not specialized, then maybe something like that would work fine with your case :

#include <vector>
#include <iostream> 
#include <algorithm>

class Bool
{
public:

    Bool(): m_value(){}
    Bool( bool value ) : m_value(value){}

    operator bool() const { return m_value; }

    // the following operators are to allow bool* b = &v[0]; (v is a vector here).
    bool* operator& () { return &m_value; }
    const bool* operator& () const { return &m_value; }

private:

    bool m_value;

};




int main()
{
    std::vector<Bool> working_solution(10, false);


    working_solution[5] = true;
    working_solution[7] = true;


    for( int i = 0; i < working_solution.size(); ++i )
    {
        std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::sort( working_solution.begin(), working_solution.end());
    std::cout<< "--- SORTED! ---" << std::endl;

    for( int i = 0; i < working_solution.size(); ++i )
    {
            bool* b = &working_solution[i]; // this works!

        std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::cin.get();
    return 0;
}

I tried this with VC9 and it seems to work fine. The idea of the Bool class is to simulate the bool type by providing the same behavior and size (but not the same type). Almost all the work is done by the bool operator and the default copy constructors here. I added a sort to be sure it react as assumed when using algorithms.

Not sure it would suit all cases. If it's right for your needs, it would be less work than rewriting a vector-like class...

like image 29
Klaim Avatar answered Oct 07 '22 08:10

Klaim


Depends on your needs. I would go for either std::vector<unsigned char>. Writting a wrapper can be fine if you only use a subset of the functionality, else it will become a nightmare.

like image 20
David Rodríguez - dribeas Avatar answered Oct 07 '22 06:10

David Rodríguez - dribeas