Comme (espérons-le) nous le savons tous, il vector<bool>
est totalement cassé et ne peut pas être traité comme un tableau C. Quelle est la meilleure façon d'obtenir cette fonctionnalité? Jusqu'à présent, les idées auxquelles j'ai pensé sont:
- Utilisez
vector<char>
plutôt un ou - Utilisez une classe wrapper et ayez
vector<bool_wrapper>
Comment gérez-vous ce problème? J'ai besoin de la c_array()
fonctionnalité.
En guise de question secondaire, si je n'ai pas besoin de la c_array()
méthode, quelle est la meilleure façon d'aborder ce problème si j'ai besoin d'un accès aléatoire? Dois-je utiliser un deque ou autre chose?
Éditer:
- J'ai besoin d'un dimensionnement dynamique.
- Pour ceux qui ne savent pas, il
vector<bool>
est spécialisé pour que chacunbool
prenne 1 bit. Ainsi, vous ne pouvez pas le convertir en un tableau de style C. - Je suppose que "wrapper" est un peu un abus de langage. Je pensais à quelque chose comme ça:
Bien sûr, alors je dois lire dans un en my_bool
raison de problèmes d'alignement possibles :(
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
vector<bool>
je viens de provoquer un bogue de course aux données dans mon code, car je m'attendais à ce que différents threads puissent modifier différents éléments du vecteur en même temps en toute sécurité. Résolu en utilisantdeque<bool>
.Réponses:
À utiliser
std::deque
si vous n'avez pas besoin du tableau, oui.Sinon, utilisez une alternative
vector
qui ne se spécialise pasbool
, comme celle de Boost Container .la source
C'est un problème intéressant.
Si vous avez besoin de ce qui aurait été un std :: vector s'il n'était pas spécialisé, alors peut-être que quelque chose comme ça fonctionnerait bien avec votre cas:
J'ai essayé cela avec VC9 et cela semble fonctionner correctement. L'idée de la classe Bool est de simuler le type booléen en fournissant le même comportement et la même taille (mais pas le même type). Presque tout le travail est effectué par l'opérateur booléen et les constructeurs de copie par défaut ici. J'ai ajouté un tri pour être sûr qu'il réagit comme supposé lors de l'utilisation d'algorithmes.
Pas sûr que cela convienne à tous les cas. Si cela répond à vos besoins, ce serait moins de travail que de réécrire une classe de type vectoriel ...
la source
sizeof(bool)
n'est pas obligé d'être1
"operator bool() const
en unoperator bool&()
. Cela rend miroir le comportement d'un simple , bool mieux , car il prend en charge l' affectation , etc. dans des cas commev[0] = true;
je ne vois vraiment pas un problème avec ce changement, alors que je pourrais faire le modifier?Dépend de vos besoins. J'irais pour l'un ou l'autre
std::vector<unsigned char>
. L'écriture d'un wrapper peut être bien si vous n'utilisez qu'un sous-ensemble de la fonctionnalité, sinon cela deviendra un cauchemar.la source
unsigned char
est toujours un seul octet alorsuint8_t
que l'implémentation peut ne pas prendre en charge.uint_fast8_t
pourrait fonctionner si l'intention est de préciser qu'il s'agit d'un seul octet et non d'un caractère, mais vous pourriez aussi bien utiliserstd::byte
alorsboost::container::vector<bool>
:la source
Pensez à utiliser un vecteur <int>. Une fois que vous avez dépassé la compilation et la vérification de type, bool et int ne sont que des mots machine (modifier: apparemment ce n'est pas toujours vrai; mais ce sera vrai sur de nombreuses architectures PC). Dans les cas où vous souhaitez convertir sans avertissement, utilisez "bool foo = !! bar", qui convertit zéro en faux et non-zéro en vrai.
Un vecteur <char> ou similaire utilisera moins d'espace, bien qu'il ait également le potentiel de prendre un (très petit) coup de vitesse dans certaines circonstances, car les caractères sont inférieurs à la taille du mot machine. C'est, je crois, la principale raison pour laquelle les booléens sont implémentés en utilisant des ints au lieu de chars.
Si vous voulez vraiment une sémantique propre, j'aime aussi la suggestion de créer votre propre classe booléenne - ressemble à un booléen, agit comme un booléen, mais trompe la spécialisation des modèles.
Aussi, bienvenue dans le club des personnes qui souhaitent que la spécialisation vector <bool> soit supprimée du standard C ++ (avec bit_vector pour la remplacer). C'est là que tous les enfants cools traînent :).
la source
Ce problème a déjà été discuté sur comp.lang.c ++. Modéré. Solutions proposées:
std::allocator
) et votre propre spécialisation vectorielle;std::deque
(comme le plus tôt a été recommandé dans l'un des livres S. Mayers) - mais ce n'est pas pour vos besoins;bool
wrapper POD ;char
/int
/ etc) avec la même taille qu'à labool
placebool
;Aussi tôt j'ai vu une proposition de comité standard - introduire une macro (quelque chose comme
STD_VECTOR_BOOL_SPECIAL
) pour interdire cette spécialisation - mais AFAIK cette proposition n'a pas été mise en œuvre dans les implémentations stl et n'a pas été approuvée.Il semble que votre problème n'ait aucun moyen de le faire correctement ... Peut-être en C ++ 0x.
la source
La réponse la plus simple est d'utiliser
vector<struct sb>
oùsb
eststruct {boolean b};
. Alors vous pouvez direpush_back({true})
. Il semble bon.la source
Ma solution de contournement préférée est une
vector
énumération étendue qui a un type sous-jacent debool
. Cela se rapprochevector<bool>
beaucoup de ce que nous aurions eu si le comité ne s'était pas spécialisé.Vous aurez vos propres opinions sur la sagesse d'adopter des moulages vers / depuis
bool
:la source