Установка boost_bitset из строки - PullRequest
5 голосов
/ 31 марта 2009

Динамический битовый набор

У меня есть случай, когда мне нужно заполнить

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

Можете ли вы предложить, как это сделать? Поэтому мне нужно придумать функцию

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

     //populate bitMap from a string buffer
}

1 Ответ

9 голосов
/ 31 марта 2009

Если у вас есть такие двоичные данные:

string buffer = "0101001111011";

Вы хотите инициализировать его следующим образом (оказывается, есть конструктор , который обрабатывает этот случай):

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

Если вам нужны необработанные данные, используйте конструктор итератора :

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

Это в конечном итоге выделяет необходимую память дважды, так что вам может быть лучше с выделением стека и подкачкой. Или вы можете просто подождать до C ++ 0x и позволить семантике перемещения делать свое дело.

// 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: Чтобы выяснить, почему первые версии выделяют вдвое больше памяти:

Взгляните на другой способ написания первой версии:

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
}

Если вы соедините эти две строки вместе, как в первом примере, вы все равно получите временную конструкцию в стеке с последующим назначением. В 1. boost необходимо выделить достаточно памяти для всего набора битов. В 2, boost должен снова выделить достаточно памяти для хранения того же набора битов, а затем скопировать значения. Вполне возможно, что у bitMap уже достаточно памяти, поэтому ему не всегда нужно перераспределять, но также возможно, что он все равно освободит свою резервную память и перераспределит с нуля.

Большинство контейнеров, которые подходят для пресс-формы stl, также имеют функцию свопинга, которую вы можете использовать вместо назначения, когда намереваетесь выбросить одну сторону свопа. Обычно это O (1), а не броски, так как они часто включают в себя обмен указателями. Смотрите это ПОЛУЧИЛ по другой причине, почему они полезны.

В C ++ 0X вы сможете использовать присваивание и при этом пользоваться преимуществами свопинга. Поскольку вы можете перегружать r-значения (например, временные), контейнер знает, что когда вы назначаете временные значения, он знает, что он может каннибализировать временные значения и, в основном, выполнять обмен. В блоге Visual Studio Team Blog подробно описаны rvalues ​​и семантика перемещения .

...