2009-03-30 3 views
5

Dynamic bitsetEinstellung Boost dynamic_bitset aus einem String

Ich habe einen Anwendungsfall, wo ich

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

zu füllen brauchen Können Sie, wie um dies zu realisieren. Also muss ich mit einer Funktion

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

    //populate bitMap from a string buffer 
} 
+0

Sie müssen mindestens angeben, wie die Zeichenfolge interpretiert werden soll. Sind es nur die Zeichen 1 und 0 und das sind die Bits? Oder ist es eine hexadezimale Darstellung? Oder möchten Sie, dass das rohe Speichern der Zeichenfolgen in das Bitset übernommen wird? –

+0

Ist der Zeichenfolgenpuffer voll mit Binärdaten oder Stringdaten? I.e. ist es so initialisiert: string buffer = "1111101001010000"; oder dieser string buffer = {0xfa, 0x50}; – Eclipse

+0

was gleichen String-Puffer? es ist "01010111" oder "asdfvfdsa"? – bayda

Antwort

9

kommen Wenn Sie diese binäre Daten wie haben:

string buffer = "0101001111011"; 

Sie wollen es initialisieren, wie dies (stellt sich heraus, es ist ein constructor, dass dieser Fall behandelt):

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

Wenn Sie die Rohdaten möchten, verwenden Sie die iterator constructor:

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

Diese ordnen den benötigten Speicher zweimal zu, so dass Sie mit einer Stapelzuweisung und einem Swap möglicherweise besser dran sind. Oder Sie können einfach auf C++ 0x warten und die Umzugs-Semantik 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); 
} 

Edit: Um zu klären, warum die ersten Versionen doppelt so viel Speicher zuweisen:

einen Blick auf eine andere Art und Weise Nehmen Sie 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 setzen Linien zusammen, wie im ersten Beispiel, 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 zugewiesen werden. In 2 muss Boost erneut genug Speicher zuweisen, um den gleichen Bitsatz zu speichern, und dann die Werte kopieren. Es ist möglich, dass BitMap bereits über genügend Speicher verfügt, so dass es nicht immer neu zugeordnet werden muss, aber es ist auch möglich, dass es den Hintergrundspeicher freigibt und von Grund auf neu zugewiesen wird.

Die meisten Container, die in die STL-Form passen, haben auch eine Swap-Funktion, die Sie anstelle der Zuweisung verwenden können, wenn Sie beabsichtigen, eine Seite des Swaps wegzuwerfen. Diese sind normalerweise O (1) und nicht werfen, da sie oft nur ein paar Zeiger vertauschen. Sehen Sie diese GotW aus einem anderen Grund, warum diese nützlich sind.

In C++ 0X können Sie die Zuweisung verwenden und trotzdem die Vorteile von Swap nutzen. Da Sie r-Werte (wie das temporäre) überladen können, weiß der Container, dass wenn Sie ein temporäres zuweisen, es weiß, dass es die Temperatur kannibalisieren kann und grundsätzlich einen Swap durchführt. Der Visual Studio-Team-Blog hat rvalues ​​behandelt und die Semantik verschoben quite well here.

+0

Hey, Josh, ich verstehe nicht, wenn du sagst, dass die Nicht-Swap-Versionen das Ding zweimal zuweisen ... könntest du das erklären? Vielen Dank! –