Wie (hoffentlich) wir alle wissen, vector<bool>
ist es total kaputt und kann nicht als C-Array behandelt werden. Was ist der beste Weg, um diese Funktionalität zu erhalten? Bisher habe ich an folgende Ideen gedacht:
- Verwenden Sie
vector<char>
stattdessen ein oder - Verwenden Sie eine Wrapper-Klasse und haben
vector<bool_wrapper>
Wie geht ihr mit diesem Problem um? Ich brauche die c_array()
Funktionalität.
Als Nebenfrage: Wenn ich die c_array()
Methode nicht benötige , wie kann ich dieses Problem am besten angehen, wenn ich wahlfreien Zugriff benötige? Soll ich eine Deque oder etwas anderes verwenden?
Bearbeiten:
- Ich brauche eine dynamische Dimensionierung.
- Für diejenigen, die es nicht wissen,
vector<bool>
ist spezialisiert, so dass jedesbool
1 Bit dauert. Daher können Sie es nicht in ein Array im C-Stil konvertieren. - Ich denke, "Wrapper" ist ein bisschen eine Fehlbezeichnung. Ich dachte so etwas:
Natürlich muss ich dann my_bool
aufgrund möglicher Ausrichtungsprobleme in ein lesen :(
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
vector<bool>
gerade ein Datenrennen-Fehler in meinem Code verursacht, da ich erwartet hatte, dass verschiedene Threads verschiedene Elemente im Vektor gleichzeitig sicher ändern können. Gelöst mitdeque<bool>
.Antworten:
Verwenden
std::deque
Sie diese Option, wenn Sie das Array nicht benötigen.Verwenden Sie andernfalls eine Alternative
vector
, auf die Sie sich nicht spezialisiert habenbool
, z. B. die im Boost-Container .quelle
Das ist ein interessantes Problem.
Wenn Sie einen std :: vector benötigen, der nicht spezialisiert wäre, funktioniert so etwas möglicherweise gut für Ihren Fall:
Ich habe dies mit VC9 versucht und es scheint gut zu funktionieren. Die Idee der Bool-Klasse besteht darin, den Bool-Typ zu simulieren, indem das gleiche Verhalten und die gleiche Größe (jedoch nicht der gleiche Typ) bereitgestellt werden. Fast die gesamte Arbeit wird hier vom Bool-Operator und den Standard-Kopierkonstruktoren ausgeführt. Ich habe eine Sortierung hinzugefügt, um sicherzustellen, dass sie bei Verwendung von Algorithmen wie angenommen reagiert.
Ich bin mir nicht sicher, ob es für alle Fälle geeignet ist. Wenn es für Ihre Bedürfnisse richtig ist, wäre es weniger Arbeit als das Umschreiben einer vektorähnlichen Klasse ...
quelle
sizeof(bool)
nicht sein1
"operator bool() const
zu ändernoperator bool&()
. Dadurch spiegelt es das Verhalten eines einfachen Bools besser wider, da es die Zuweisung usw. unterstützt, wennv[0] = true;
ich wirklich kein Problem mit dieser Änderung sehe. Darf ich also die Bearbeitung vornehmen?Kommt auf deine Bedürfnisse an. Ich würde für beide gehen
std::vector<unsigned char>
. Das Schreiben eines Wrappers kann in Ordnung sein, wenn Sie nur eine Teilmenge der Funktionalität verwenden, da dies sonst zu einem Albtraum wird.quelle
unsigned char
ist immer ein einzelnes Byte, wird jedochuint8_t
möglicherweise von der Implementierung nicht unterstützt.uint_fast8_t
könnte zwar funktionieren , wenn die Absicht ist es deutlich zu machen , es ist ein einziges Byte ist und kein Zeichen, aber Sie könnten als auch verwenden ,std::byte
dannboost::container::vector<bool>
::quelle
Verwenden Sie einen Vektor <int>. Sobald Sie die Kompilierung und Typprüfung hinter sich gelassen haben, sind bool und int nur noch Maschinenwörter (bearbeiten: Anscheinend ist dies nicht immer der Fall; wird aber auf vielen PC-Architekturen zutreffen). In den Fällen, in denen Sie ohne Warnung konvertieren möchten, verwenden Sie "bool foo = !! bar", das Null in falsch und Nicht-Null in wahr konvertiert.
Ein Vektor <char> oder ähnliches benötigt weniger Platz, kann jedoch unter bestimmten Umständen auch einen (sehr kleinen) Geschwindigkeitstreffer verursachen, da die Zeichen kleiner als die Maschinenwortgröße sind. Dies ist meiner Meinung nach der Hauptgrund dafür, dass Bools mit Ints anstelle von Zeichen implementiert werden.
Wenn Sie wirklich eine saubere Semantik wollen, mag ich auch den Vorschlag, eine eigene Boolesche Klasse zu erstellen - sieht aus wie ein Bool, verhält sich wie ein Bool, täuscht aber die Template-Spezialisierung.
Willkommen auch im Club der Leute, die möchten, dass die Vektor <bool> -Spezialisierung aus dem C ++ - Standard gestrichen wird (mit bit_vector als Ersatz). Hier hängen all die coolen Kids rum :).
quelle
Dieses Problem wurde bereits in comp.lang.c ++. Moderiert diskutiert . Lösungsvorschläge:
std::allocator
) und Ihre eigene Vektorspezialisierung;std::deque
(wie früh in einem der Bücher S. Mayers empfohlen wurde) - aber dies nicht für Ihre Anforderungen;bool
Wrapper herstellen;char
/int
/ etc) mit der gleichen Größe wie ;bool
bool
Ebenfalls früh sah ich einen Vorschlag für ein Standardkomitee - Einführung eines Makros (so etwas wie
STD_VECTOR_BOOL_SPECIAL
), um diese Spezialisierung nicht zuzulassen -, aber AFAIK dieser Vorschlag wurde nicht in STL-Implementierungen implementiert und nicht genehmigt.Es scheint, dass Ihr Problem keine Möglichkeit hat, dies gut zu machen ... Vielleicht in C ++ 0x.
quelle
Die einfachste Antwort ist verwenden,
vector<struct sb>
wosb
iststruct {boolean b};
. Dann kannst du sagenpush_back({true})
. Es scheint gut.quelle
Meine bevorzugte Problemumgehung ist eine
vector
Aufzählung mit Gültigkeitsbereich, der ein zugrunde liegender Typ vonbool
. Dies kommt dem sehr nahe, wasvector<bool>
wir gehabt hätten, wenn das Komitee es nicht spezialisiert hätte.Sie werden Ihre eigene Meinung über die Weisheit haben, Casts zu / von zu umarmen
bool
:quelle