Является ли использование объектов std::vector <bool> в С++ допустимым, или я должен использовать альтернативу?
Я работаю с определенным количеством бит (я держу трехмерный массив бит, поэтому размер увеличивается кубически - не менее 512 бит), и нужно перевернуть их по отдельности. Прямо сейчас, только на компьютере, я использую тип bool
, так как память не является проблемой. Я планирую перенести код на микроконтроллер в будущем, и поэтому может потребоваться вычислительная мощность и требования к памяти. Прямо сейчас, я просто хочу скорость.
Затем я нашел объект std::bitset
из С++ STL, но я не могу определить размер битов во время выполнения. Затем я обнаружил, что std::vector<byte>
имеет специальный инициализатор для хранения их как битов (вместо целых байтов или 4 байта), но затем нашел этот раздел в Википедии:
Стандартная библиотека определяет специализацию шаблона vector
для bool
. Описание этой специализации показывает, что реализация должна упаковывать элементы так, чтобы каждый bool
использовал только один бит памяти. Это широко считается ошибкой. [...] Среди стандартного комитета С++ и рабочей группы библиотеки существует общее мнение о том, что vector<bool>
должно быть устаревшим и впоследствии удалено из стандартной библиотеки, в то время как функциональность будет повторно введена под другим именем.
Теперь вы, вероятно, увидите мое желание использовать объект vector<bool>
, но после прочтения этого я рассматриваю возможность использования чего-то другого. Единственная проблема в том, что я не уверен, что использовать. Мне было любопытно, но почему они заявляют, что функциональность должна быть повторно введена (хотя и под другим именем).
Итак, мой вопрос: приемлемо ли использование объектов vector<bool>
(если они являются частью STL)? Являются ли они частью стандарта С++?
Если их использование неприемлемо, существует ли приемлемое альтернативное решение (вне меня я сам определяю специальный контейнер)? У меня есть несколько идей, но мне просто интересно, есть ли у кого-то лучшее решение. Кроме того, я хотел бы избежать использования больших библиотек (опять же, я хочу, в конце концов, передать этот код на микроконтроллер).
Ответы
Ответ 1
Нет ничего плохого в vector<bool>
, за исключением того, что он не эквивалентен vector<T>
, если T - целочисленный тип, эквивалентный bool. Это проявляется только в производительности (процессоры получают доступ только к байтам за раз, где в vector<bool>
каждый элемент хранится в одном бите) и доступ к памяти (ссылка на первый элемент vector<bool>
не эквивалентна массиву типа с любым другим vector<T>
.
Это часть стандарта, к сожалению: см. раздел 23.3.7
(С++ 0x FDIS).
Ответ 2
В "Эффективном STL" , пункт 18, Скотт Мейерс рекомендовал: "Избегайте использования vector <bool> .":
В качестве контейнера STL действительно есть две ошибки: вектор <bool> . Во-первых, это не контейнер STL. Во-вторых, это не удерживайте bools. Кроме этого, нечего возражать.
Ответ 3
Существует boost.dynamic_bitset, который почти идентичен std:: bitset, за исключением того, что его размер указан во время выполнения. Если вы не заинтересованы в зависимости от форсирования, его исходный код (который полностью содержится в его заголовочном файле) может, по крайней мере, дать больше идей о том, как можно записать такой контейнер.
Ответ 4
Критика состоит в том, что vector<bool>
является единственным стандартным контейнером, который не полностью соответствует стандартным требованиям контейнера. Это немного неожиданно.
Другое дело, что vector<bool>
заставляет оптимизацию пространства для всех (путем хранения бит), когда, возможно, некоторые пользователи предпочли бы оптимизацию скорости.
Кроме этого, основное отклонение состоит в том, что контейнер не может вернуть ссылку на своих членов, поскольку он не хранит никаких bools. Это приведет к тому, что алгоритм нечетной стандартной библиотеки не скомпилируется для vector<bool>
.
Если вы можете жить с этим, и он подходит для ваших потребностей во всем остальном, вполне нормально использовать его.
Ответ 5
Нет ничего плохого в правильном использовании vector<bool>
, так же как и ничего не с auto_ptr
- если вы знаете недостатки и неожиданности перед продолжением.
Ответ 6
Я бы предложил использовать библиотеку BITSCAN в качестве альтернативы Boost: dynamic_bitset. Сравнительный обзор можно найти здесь.
Ответ 7
Альтернативой может быть BitMagic, хотя я не уверен, что он работает с любой другой архитектурой, чем x86 (она сильно оптимизирована с использованием SIMD).