Wie hängen die verschiedenen Größen zusammen?

8

Zur Zeit habe ich ein Szenario, bei dem ich prüfen möchte, ob das Schreiben einer gegebenen Zeichenkette in einen Dateistrom die Datei über eine gegebene Größe hinaus vergrößert (dies wird für die Protokolldateirotation verwendet). Jetzt gibt std::ofstream::tellp() eine streampos zurück, aber std::string::size() gibt eine size_t zurück. Der Effekt ist, dass dies nicht funktioniert:

%Vor%

weil anscheinend eine mehrdeutige Überladung von operator + für diese Typen besteht. Dies führt mich zu zwei Fragen:

  1. Wie kann ich die obige Mehrdeutigkeit beheben?
  2. Wie hängen die verschiedenen Typen ( size_t , streamsize , streampos , streamoff ) zusammen? Wann können sie sicher konvertiert werden und was sind mögliche Fallstricke? Ich bin im Allgemeinen über diese Typen verwirrt. Ich weiß nur, dass sie implementierungsabhängig sind und bestimmte Garantien geben (zB size_t ist immer groß genug, um die Größe des large-Objekts zu halten, das in den Speicher der Architektur passt, für die die Anwendung kompiliert wurde) Welche Garantien gibt es für die Interoperabilität dieser Typen (siehe Beispiel oben oder Vergleich eines streamsize mit einem size_t )?
Björn Pollex 10.03.2011, 15:41
quelle

4 Antworten

4

Sie sollten in der Lage sein, das Ergebnis von tellp in ein std::string::size_type durch Casting zu konvertieren.

static_cast<std::string::size_type>(out_stream.tellp()) + string.size() < limit

EDIT: Das ist sicher, weil Ihr Stream-Offset nie negativ sein wird und sicher in einen vorzeichenlosen Wert konvertiert wird.

    
Mark B 10.03.2011, 15:44
quelle
3

Die eigentliche Frage ist: Was ist die Art von Limit? Der übliche Weg Testen, ob noch Platz ist, ist normalerweise:     limit - out_stream.tellp () & gt; = string.size () Aber Sie müssen sicherstellen, dass das Limit einen Typ hat, aus dem out_stream.tellp () kann subtrahiert werden.

In der Theorie ist streampos nicht konvertierbar oder vergleichbar mit einem Integral Typ, oder das, umgewandelt in einen ganzzahligen Typ, gibt es signifikant Information. Und dazu brauchte es Unterstützung Subtraktion oder Vergleich Angelegenheit. In der Praxis glaube ich nicht, dass Sie sich zu viele Sorgen machen müssen Umwandlung in einen integralen Typ existiert und monoton (obwohl vielleicht auf einem exotischen Mainframe ...). Aber du kannst dir nicht sicher sein Arithmetik mit ihm wird funktionieren, also würde ich es wahrscheinlich lieber konvertieren explizit auf eine streamsize (die garantiert ein signiertes Integral ist Art). (Unabhängig davon, wie Sie das Problem angehen, müssen Sie handeln mit der Tatsache, dass string.size () eine size_t zurückgibt, die benötigt wird nicht signiert sein, während streamsize signiert werden muss.)

In Bezug auf Ihre zweite Frage:     size_t ist ein typedef zu einem vorzeichenlosen ganzzahligen Typ, der groß genug ist         Geben Sie die Größe eines möglichen Objekts an,     streamsize ist ein typedef zu einem vorzeichenbehafteten ganzzahligen Typ, groß genug um         Geben Sie die Größe eines "Objekts" in einem Stream an,     streamoff ist ein typedef zu einem integralen Typ, der spezifiziert werden kann         die Position eines Bytes in einer Datei und     streampos ist ein typedef zu fpos, wo         etwas ist ein Typ, mit dem man den Zustand aufrechterhalten kann         der Fall eines Multibyte-Streams. Der Standard stellt sehr wenige Anforderungen an die Beziehungen zwischen ihnen (und einige der wenigen, die es macht, sind mathematisch unmöglich zu realisieren), also bist du ziemlich allein.

    
James Kanze 10.03.2011 17:28
quelle
1

Ich glaube, der Standard besagt, dass streamsize implementierungsspezifisch ist, also keine Hilfe. Für eine praktische Antwort können Sie die Header überprüfen, wo diese typedef ed sind.

Wenn man bedenkt, dass size_t 4 Bytes lang sein könnte, während Ihre Anwendung könnte möglicherweise mit einem Strom von mehr als 4GB Länge arbeiten könnte, glaube ich, dass Sie für die Interoperabilität auf einen Typ mit bekannter Größe konvertieren müssen für eine luftdichte Lösung.

Wenn Sie wissen, dass size_t oder streamsize 8 Bytes lang ist, können Sie diesen Typ natürlich direkt verwenden, wenn Sie wissen (vielleicht mit einer Kompilierungszeit-Assertion). Wenn Sie einen Stream haben, dessen Länge nicht in 8 Bytes passt, haben Sie größere Probleme als beim richtigen Typ.

    
Jon 10.03.2011 15:51
quelle
0

Wenn Sie große Größen haben, ist unsigned long long nicht das Beste, was Sie bekommen können. Wenn das nicht groß genug ist, was sonst noch?

    
Bo Persson 10.03.2011 16:28
quelle

Tags und Links