Como (esperançosamente) todos nós sabemos, vector<bool>
está totalmente quebrado e não pode ser tratado como um array C. Qual é a melhor maneira de obter essa funcionalidade? Até agora, as ideias em que pensei são:
- Use um
vector<char>
, ou - Use uma classe de wrapper e tenha
vector<bool_wrapper>
Como vocês lidam com esse problema? Eu preciso da c_array()
funcionalidade.
Como questão lateral, se eu não precisar do c_array()
método, qual é a melhor maneira de abordar esse problema se eu precisar de acesso aleatório? Devo usar um deque ou outra coisa?
Editar:
- Eu preciso de dimensionamento dinâmico.
- Para quem não sabe,
vector<bool>
é especializado para que cada umbool
leve 1 bit. Portanto, você não pode convertê-lo em uma matriz de estilo C. - Eu acho que "invólucro" é um pouco impróprio. Eu estava pensando algo assim:
Claro, então eu tenho que ler em um my_bool
devido a possíveis problemas de alinhamento :(
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
vector<bool>
acabei de causar um bug de corrida de dados no meu código, já que esperava que diferentes threads pudessem modificar diferentes elementos no vetor ao mesmo tempo com segurança. Resolvido usandodeque<bool>
.Respostas:
Use
std::deque
se você não precisar do array, sim.Caso contrário, use uma alternativa
vector
que não seja especializadabool
, como a do Boost Container .fonte
Esse é um problema interessante.
Se você precisa do que seria um std :: vector se não fosse especializado, talvez algo assim funcione bem com o seu caso:
Tentei fazer isso com o VC9 e parece funcionar bem. A ideia da classe Bool é simular o tipo bool fornecendo o mesmo comportamento e tamanho (mas não o mesmo tipo). Quase todo o trabalho é feito pelo operador bool e pelos construtores de cópia padrão aqui. Eu adicionei uma classificação para ter certeza de que ela reagirá conforme o esperado ao usar algoritmos.
Não tenho certeza se serviria para todos os casos. Se for certo para suas necessidades, daria menos trabalho do que reescrever uma classe de vetor ...
fonte
sizeof(bool)
não é obrigatório1
"operator bool() const
para umoperator bool&()
. Isso faz com que ele espelhe melhor o comportamento de um bool simples, pois oferece suporte a atribuição, etc., em casos comov[0] = true;
eu realmente não consigo ver um problema com essa alteração, então posso fazer a edição?Depende de suas necessidades. Eu iria para qualquer um
std::vector<unsigned char>
. Escrever um wrapper pode ser bom se você usar apenas um subconjunto da funcionalidade, caso contrário, se tornará um pesadelo.fonte
unsigned char
é sempre um único byte, enquantouint8_t
pode não ser suportado pela implementação.uint_fast8_t
pode funcionar, porém, se a intenção for deixar claro que é um único byte e não um caractere, mas você também pode usarstd::byte
entãoboost::container::vector<bool>
:fonte
Considere usar um vetor <int>. Depois de passar a compilação e a verificação de tipo, bool e int são apenas palavras de máquina (editar: aparentemente, isso nem sempre é verdade; mas será verdade em muitas arquiteturas de PC). Nos casos em que você deseja converter sem aviso, use "bool foo = !! bar", que converte zero em falso e diferente de zero em verdadeiro.
Um vetor <char> ou similar usará menos espaço, embora também tenha o potencial de sofrer um impacto de velocidade (muito pequeno) em algumas circunstâncias, porque os caracteres são menores que o tamanho da palavra da máquina. Esta é, creio eu, a principal razão pela qual os bools são implementados usando ints em vez de chars.
Se você realmente quiser uma semântica limpa, também gosto da sugestão de fazer sua própria classe booleana - parece um bool, age como um bool, mas engana a especialização do modelo.
Além disso, bem-vindo ao clube de pessoas que desejam que a especialização em vetor <bool> seja retirada do padrão C ++ (com bit_vector para substituí-lo). É onde todas as crianças legais se divertem :).
fonte
Este problema já foi discutido em comp.lang.c ++. Moderated. Soluções propostas:
std::allocator
) e sua própria especialização vetorial;std::deque
(já foi recomendado em um dos livros S. Mayers) - mas não para suas necessidades;bool
invólucro POD ;char
/int
/ etc) com o mesmo tamanho quebool
em vezbool
;Também no início eu vi uma proposta de comitê padrão - introduzir macro (algo como
STD_VECTOR_BOOL_SPECIAL
) para desautorizar esta especialização - mas AFAIK esta proposta não foi implementada em implementações de stl e não foi aprovada.Parece que seu problema não tem como resolver isso direitinho ... Talvez em C ++ 0x.
fonte
A resposta mais simples é usar
vector<struct sb>
ondesb
estástruct {boolean b};
. Então você pode dizerpush_back({true})
. Parece bom.fonte
Minha solução alternativa preferida é um
vector
enum com escopo definido que tem um tipo subjacente debool
. Isso chega bem perto dovector<bool>
que teríamos se o comitê não tivesse se especializado nisso.Você terá suas próprias opiniões sobre a sabedoria de abraçar moldes de / para
bool
:fonte