2009-03-30 12 views
5

Dynamic bitsetUstawienie doładowania dynamic_bitset z ciągiem

Mam przypadku użycia, gdzie muszę wypełnić

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

można sugerować, jak go o to. Więc muszę wymyślić funkcji

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

    //populate bitMap from a string buffer 
} 
+0

Musisz przynajmniej określić sposób interpretacji ciągu znaków. Czy to tylko znaki 1 i 0 i czy to są bity? Czy jest to reprezentacja heksadecymalna? A może chcesz, aby surowe przechowywanie znaków ciągu trafiło do zestawu bitów? –

+0

Czy Twój bufor strun jest pełen danych binarnych lub danych ciągów? To znaczy. jest zainicjalizowany w następujący sposób: string buffer = "1111101001010000" ;, lub ten bufor ciągów = {0xfa, 0x50}; – Eclipse

+0

jaki jest bufor tego samego ciągu? to jest "01010111" lub "asdfvfdsa"? – bayda

Odpowiedz

9

Jeśli masz dane binarne tak:

string buffer = "0101001111011"; 

chcesz zainicjować go tak (okazuje się, że to constructor który obsługuje ten przypadek):

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

Jeśli chcesz surowych danych, użyj iterator constructor:

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

Powodują one dwukrotne przydzielenie wymaganej pamięci, więc możesz być lepiej z alokacją stosów i wymianą. Lub możesz po prostu poczekać aż C++ 0x i pozwolić semantykę ruchu zrobić swoje.

// 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: Aby wyjaśnić, dlaczego pierwsze wersje przeznaczyć dwa razy więcej pamięci:

spojrzeć na inny sposób napisać pierwszą wersję:

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 
} 

Jeśli umieścisz te dwa linie razem, tak jak w pierwszym przykładzie, nadal otrzymujesz tymczasowo skonstruowane na stosie, a następnie zadanie. W 1. boost trzeba przydzielić wystarczającą ilość pamięci dla całego zestawu bitów. W 2, boost musi przydzielić ponownie wystarczająco dużo pamięci, aby pomieścić ten sam zestaw bitów, a następnie skopiować wartości. Możliwe, że bitmapa ma już wystarczającą ilość pamięci, więc nie zawsze musi się ponownie przesuwać, ale możliwe jest również, że zwolni ona swoją pamięć kopii zapasowej i zrestartuje od nowa.

Większość kontenerów dopasowanych do formy standardowej ma również funkcję zamiany, której można użyć w miejsce zadania, gdy zamierza się wyrzucić jedną stronę wymiany. Zazwyczaj są to O (1) i nie są rzucane, ponieważ często wymagają tylko wymiany niektórych wskaźników. Zobacz ten GotW z innego powodu, dlaczego są one przydatne.

W C++ 0X będziesz mógł korzystać z zadań i nadal będziesz mieć zalety zamiany. Ponieważ możesz przeciążyć wartości r (takie jak tymczasowe), kontener wie, że kiedy przypisujesz tymczasowy, wie, że może on kanibalizować tymczasowo i w zasadzie zrobić zamianę. Blog zespołu Visual Studio zawierał wartości r/i przenosił semantykę quite well here.

+0

Hej, Josh, nie rozumiem, kiedy mówisz, że wersje bez zamiany przydzielają rzecz dwa razy ... czy mógłbyś to wyjaśnić? Dzięki! –