Является ли использование объектов std :: vector <bool>в C ++ приемлемым или я должен использовать альтернативу? - PullRequest
24 голосов
/ 21 июля 2011

Я работаю с определенным пользователем количеством битов (я держу трехмерный массив битов, поэтому размер увеличивается кубически - предположим, не менее 512 бит), и мне нужно отразить их каждый в отдельности.Прямо сейчас, просто на компьютере, я использую тип bool, так как память не проблема.Я планирую перенести код на микроконтроллер в будущем, поэтому могут возникнуть проблемы с вычислительной мощностью и требованиями к памяти.Хотя сейчас мне нужна скорость.

Затем я нашел объект std::bitset из C ++ STL , но не могу определить размер набора битов во время выполнения.Затем я обнаружил, что std::vector<byte> имеет специальный инициализатор для хранения их в виде битов (вместо целых байтов или 4 байтов), но затем нашел этот раздел в Википедии:

Стандартная библиотека определяет специализацию шаблона vector для bool.Описание этой специализации указывает, что реализация должна упаковать элементы так, чтобы каждый bool использовал только один бит памяти.Это широко считается ошибкой.[...] Существует общий консенсус между Комитетом по стандартизации C ++ и Рабочей группой по библиотекам, что vector<bool> должен быть признан устаревшим и впоследствии удален из стандартной библиотеки, в то время как функциональность будет вновь введена под другим именем.

Теперь вы, вероятно, видите мое желание использовать vector<bool> объект, но после прочтения я подумываю использовать что-то еще.Единственная проблема в том, что я не уверен, что использовать.Мне было любопытно, почему они утверждают, что функциональность должна быть повторно введена (хотя и под другим именем).

Итак, мой вопрос, будет ли использование vector<bool> объектовприемлемо (если они являются частью STL)?Являются ли они частью стандарта C ++?

Если их использование неприемлемо, есть ли приемлемое альтернативное решение (вне меня я определяю специальный контейнер сам)?У меня есть несколько идей, но мне просто интересно, есть ли у кого-нибудь лучшее решение.Кроме того, я хотел бы избежать использования больших библиотек (опять же, я хочу в конечном итоге перенести этот код в микроконтроллер).

Ответы [ 7 ]

24 голосов
/ 22 июля 2011

В «Эффективном STL», пункт 18 , Скотт Мейерс рекомендовал: «Избегайте использования вектора .»:

Как контейнер STL, в действительности только две вещи не так вектор . Во-первых, это не контейнер STL. Во-вторых, это не держи bools. Кроме этого, возражать не о чем.

19 голосов
/ 22 июля 2011

Нет ничего плохого в vector<bool>, за исключением того, что оно не эквивалентно vector<T>, где T - целочисленный тип, эквивалентный bool.Это показывает только производительность (процессоры обращаются только к байтам за раз, где в vector<bool> каждый элемент хранится в одном бите) и доступ к памяти (ссылка на первый элемент vector<bool> не эквивалентна массиву, подобномус любым другим vector<T>.

Это, к сожалению, является частью стандарта: см. раздел 23.3.7 (C ++ 0x FDIS).

11 голосов
/ 22 июля 2011

Существует boost.dynamic_bitset , который почти идентичен std :: bitset, за исключением того, что его размер задается во время выполнения. Если вас не интересует буст-зависимость, ее исходный код (который целиком содержится в заголовочном файле) может как минимум дать больше идей о том, как можно написать такой контейнер.

10 голосов
/ 22 июля 2011

Критика заключается в том, что vector<bool> является единственным стандартным контейнером, который не полностью не соответствует требованиям контейнера к стандарту.Это немного удивительно.

Еще один момент заключается в том, что vector<bool> заставляет всех оптимизировать пространство (сохраняя биты), когда, возможно, некоторые пользователи предпочли бы оптимизацию скорости.

Другоекроме того, основное отклонение заключается в том, что контейнер не может возвращать ссылку на свои элементы, потому что он не хранит никаких bools.Это приведет к тому, что алгоритм нечетной стандартной библиотеки не скомпилируется для vector<bool>.

Если вы можете жить с этим, и он соответствует вашим потребностям для всего остального, вполне нормально его использовать.

3 голосов
/ 28 июля 2014

Я бы предложил использовать библиотеку BITSCAN в качестве альтернативы Boost: dynamic_bitset.Сравнительный опрос можно найти здесь .

3 голосов
/ 22 июля 2011

Нет ничего плохого в правильном использовании vector<bool>, точно так же, как нет ничего плохого в auto_ptr - до тех пор, пока вы знаете недостатки и неожиданности, прежде чем продолжить.

1 голос
/ 22 июля 2011

Альтернативой может быть BitMagic , хотя я не уверен, что он работает на любой другой архитектуре, кроме x86 (она сильно оптимизирована с использованием SIMD).

...