2016-04-13 20 views
0

Ich muss Bits in Dateien speichern und std::bitset wäre perfekt dafür, denn ich brauche viele seiner Operationen, wenn ich die Struktur wieder zurücklesen. Die Klasse scheint nur aus einem Array der Bits und anderen Daten zu bestehen.Ist es in Ordnung, std :: bitset in einer Struktur zu verwenden, die vom Datenträger geschrieben und gelesen wird?

Anstatt also dieses

BYTE minuteOfDay[(60 * 24/CHAR_BIT) + ((60 * 24 % CHAR_BIT) ? 1 : 0)]; 

ich könnte dies:

std::bitset<60 * 24> minuteOfDay; 

Wenn die Klasse mit Zukunft Visual Studio Release ändern sollte und ich brauche Dateien geschrieben mit einer alten Version zu lesen, Ich denke, ich könnte immer noch den alten Header <bitset> in mein Projekt kopieren.

Aber kurz bevor man eine wirklich dumme Entscheidung trifft: Ist diese Idee irgendwie fehlerhaft, aus einem Grund, den ich momentan nicht voraussehe?

+0

Also, um klar zu sein, ist es Ihnen egal, ob es funktionieren soll oder garantiert zu arbeiten, ist es egal, ob es funktioniert? Wenn ja, warum nicht einfach testen? –

+0

Sie müssen den [zugrunde liegenden Typ] (http://en.cppreference.com/w/cpp/utility/bitset/to_ullong) weiterhin speichern und lesen. Dies ist die kleinste Einheit, die Sie verwenden können. –

+0

Ich teste es und es sieht gut aus. @ πάνταῥεῖ was meinst du? –

Antwort

1

Ist diese Idee irgendwie fehlerhaft ...?

Ja.

Zuerst die Fehlermodi: Wie Sie vermutet haben, könnte std::bitset seine interne Darstellung ändern. Abgesehen davon ist es sowieso kein Standard-Layout-Typ, daher ist der anfängliche Schreibvorgang schlecht definiert. Abgesehen von dass, wie würden Sie es wieder lesen? Vermutlich nur in einen richtig ausgerichteten Puffer einlesen und typenweise darauf tippen? Das ist auch illegal.

Zweitens, die vorgeschlagene Lösung: Kopieren Sie Ihre alten <bitset> Header entlang ist schrecklich. Es wird nicht Teil der eigentlichen Standardbibliothek sein und wird sich weiterhin illegal in den Namespace std injizieren. Es ist durchaus möglich, einige andere Code wird die native std::bitset verwenden und zu schrecklichen Fehlern führen.

Darüber hinaus kann es einfach nicht funktionieren, wenn Sie von seiner nativen Version Ihrer Standard-lib getrennt sind.

Drittens richtige Lösungen: entweder

  1. (de) serialisiert es bis zu einem gewissen wohldefinierten Format, die öffentliche Schnittstelle von std::bitset

    Note mit, dass dies ohnehin ziemlich trivial ist: std::bitset::to_string existiert bereits und Sie können eine Instanz aus dieser Zeichenkette

  2. oder neu erstellen, schreiben Sie eine Ersatzklasse, die von Ihnen kontrolliert wird und garantiert Quiz ist lly serialisierbar.Nur weil Sie nicht std::bitset kostenlos erhalten, bedeutet das nicht, dass Sie bang Felsen zusammen verwenden Sie eine rohe Char-Array.
0

Ich verstehe, dass Sie, indem Sie es in die Datei schreiben, eine Adresse der std::bitset Variable nehmen und die rohen Bytes schreiben? In diesem Fall ist die Antwort NO. Dieser Prozess wird als Entitätsserialisierung oder Entitätscodierung bezeichnet, und Sie können std::bitset (oder eine Klasse, die ihn als Mitgliedsfeld enthält) nicht serialisieren, da std::bitset nicht Standardlayout Typ ist.

+0

Nun, zumindest mit gcc und clang 'std :: bitset' [ist Standard-Layout] (http://coliru.stacked-crooked.com/a/931a854f36867094), also ist es richtig zu sagen, es ist * nicht garantiert * zu sein Standardentwurf. Auch 'struct S {int * ptr; }; 'ist Standard-Layout, aber Sie wollen es auch nicht seriell-serialisieren. –

+0

@AntonSavin, der erste Punkt ist eigentlich der gleiche für mich. Sobald Standard aufgerufen wird, ist nicht garantiert und ist nicht von ähnlicher Gewichtung. Im zweiten Teil ist es semantisch inkorrekt, aber es wird am wenigsten gut definierte Ergebnisse erzeugen, wenn Sie es im selben Programm serialisieren/deserialisieren. Nicht standardmäßige Layouttypen verfügen nicht über dieses Merkmal. – SergeyA