Frage

Dynamischer Bitsatz

Ich habe einen Anwendungsfall, den ich ausfüllen muss

boost::dynamic_bitset<unsigned char> , from a std::string buffer.

Können Sie vorschlagen, wie man das angeht?Also muss ich mir eine Funktion einfallen lassen

void populateBitSet (std::string &buffer, 
            boost::dynamic_bitset<unsigned char> & bitMap) {

     //populate bitMap from a string buffer
}
War es hilfreich?

Lösung

Wenn Sie Binärdaten wie diese haben:

string buffer = "0101001111011";

Sie möchten es so initialisieren (es stellt sich heraus, dass es eine gibt Konstrukteur das diesen Fall behandelt):

void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{        
   bitMap = boost::dynamic_bitset<unsigned char> (buffer);
}

Wenn Sie die Rohdaten benötigen, verwenden Sie die Iterator-Konstruktor:

void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{        
   bitMap = boost::dynamic_bitset<unsigned char> (buffer.begin(), buffer.end());
}

Diese weisen am Ende den benötigten Speicher doppelt zu, sodass Sie mit einer Stapelzuweisung und einem Swap möglicherweise besser dran sind.Oder Sie können einfach bis C++0x warten und die Verschiebungssemantik ihre Arbeit machen lassen.

// Unecessary in C++0x
void populateBitSet (std::string &buffer, boost::dynamic_bitset<unsigned char> & bitMap) 
{        
   boost::dynamic_bitset<unsigned char> localBitmap(buffer.begin(), buffer.end());
   bitMap.swap(localBitmap);
}

Bearbeiten:Um zu verdeutlichen, warum die ersten Versionen doppelt so viel Speicher zuweisen:

Schauen Sie sich eine andere Möglichkeit an, die erste Version zu schreiben:

typedef boost::dynamic_bitset<unsigned char> bits; // just to shorten the examples.
void populateBitSet (std::string &buffer, bits &bitMap) 
{        
   const bits &temp = bits(buffer); // 1. initialize temporary
   bitMap = temp; // 2. Copy over data from temp to bitMap
}

Wenn Sie diese beiden Zeilen wie im ersten Beispiel zusammenfügen, erhalten Sie immer noch ein temporäres Konstrukt auf dem Stapel, gefolgt von einer Zuweisung.In 1.Boost muss genügend Speicher für den gesamten Bitsatz zuweisen.In 2 muss Boost erneut genügend Speicher zuweisen, um denselben Bitsatz zu speichern, und dann die Werte kopieren.Es ist möglich, dass BitMap bereits über genügend Speicher verfügt und daher nicht immer eine Neuzuweisung erforderlich ist. Es ist jedoch auch möglich, dass der Hintergrundspeicher freigegeben und die Zuweisung trotzdem von Grund auf neu vorgenommen wird.

Die meisten Behälter, die in die STL-Form passen, verfügen auch über eine Wechselfunktion, die Sie anstelle der Zuweisung verwenden können, wenn Sie beabsichtigen, eine Seite des Wechsels wegzuwerfen.Diese sind normalerweise O(1) und nicht werfend, da sie oft nur das Vertauschen einiger Zeiger beinhalten.Sieh dir das an GotW aus einem anderen Grund, warum diese nützlich sind.

In C++0X können Sie Zuweisungen verwenden und dennoch die Vorteile von Swap nutzen.Da Sie R-Werte überladen können (z. B. temporäre Werte), weiß der Container, dass er bei der Zuweisung eines temporären Werts den temporären Wert kannibalisieren und im Grunde einen Austausch durchführen kann.Im Visual Studio Team-Blog wurden R-Werte und Bewegungssemantik behandelt ganz gut hier.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top