C ++ 11 и [17.5.2.1.3] типы битовых масок - PullRequest
7 голосов
/ 25 марта 2012

Стандарт позволяет выбирать между целочисленным типом, enum и std::bitset.

Почему разработчик библиотеки должен использовать один поверх другого при этих вариантах?

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

ctype_base::mask реализован с использованием целочисленного типа: <__locale>

regex_constants::syntax_option_type реализован с использованием перегруженных операторов enum +: <regex>

libstdc ++ проекта gcc использует все three :

ios_base::fmtflags реализовано с использованием перегруженных операторов enum +: <bits/ios_base.h>

regex_constants::syntax_option_type реализовано с использованием целочисленного типа, regex_constants::match_flag_type реализовано с использованием std::bitset
Оба: <bits/regex_constants.h>

AFAIK, gdb не может "обнаружить" битовую поля любого из этих трех вариантов, поэтому не будет разницы по сравнению с улучшенной отладкой.

Решение enum и решение целочисленного типа должны всегда использовать один и тот же пробел.std::bitset не дает гарантии того, что sizeof(std::bitset<32>) == std::uint32_t, поэтому я не вижу, что особенно привлекательно в std::bitset.

Решение enum кажется немного менее безопасным, поскольку комбинацииМаски не генерируют перечислитель.

Строго говоря, вышеупомянутое относится к n3376 , а не к FDIS (поскольку у меня нет доступа к FDIS).

ЛюбойДоступное просвещение в этой области будет оценено.

Ответы [ 3 ]

2 голосов
/ 27 марта 2012

Действительно удивительно то, что стандарт ограничивает его тремя вариантами. Почему тип класса не должен быть приемлемым? Во всяком случае ...

  • Интегральные типы - самая простая альтернатива, но им не хватает безопасности типов. Очень старый унаследованный код будет использовать их, так как они также самые старые.
  • Типы перечисления безопасны, но громоздки, и до C ++ 11 они имели тенденцию быть фиксированными до размера и диапазона int.
  • std::bitset может иметь несколько большую безопасность типов в том смысле, что bitset<5> и bitset<6> - это разные типы, и добавление запрещено, но в остальном небезопасно во многом как целостный тип. Это не было бы проблемой, если бы они разрешали типы , полученные из std::bitset<N>.

Очевидно, enum являются идеальной альтернативой, но опыт доказал, что безопасность типов действительно не нужна. Таким образом, они бросили реализаторам кость и позволили им выбрать более легкий путь. Короткий ответ, таким образом, заключается в том, что лень заставляет разработчиков выбирать int или bitset.

Немного странно, что типы, полученные из bitset, недопустимы, но на самом деле это второстепенная вещь.

Основная спецификация, представленная в этом разделе, представляет собой набор операций, определенных над этими типами (т. Е. Побитовые операторы).

2 голосов
/ 05 мая 2012

Я предпочитаю использовать enum, но иногда есть веские причины использовать целое число.Обычно ctype_base::mask взаимодействует с собственными заголовками ОС с отображением от ctype_base::mask до <ctype.h> определяемых реализацией констант, таких как _CTYPE_L и _CTYPE_U, используемых для isupper и islower и т. Д. Использование целого числаможет облегчить использование ctype_base :: mask непосредственно с нативными API-интерфейсами ОС.

Я не знаю, почему в libstdc ++ <regex> используется std::bitset.Когда этот код был зафиксирован, я сделал пометку, чтобы в какой-то момент заменить целочисленные типы перечислением, но <regex> не является для меня приоритетом.

0 голосов
/ 25 марта 2012

Почему стандарт допускает различные способы реализации библиотеки?И ответ таков: почему бы и нет?

Как вы видели, все три варианта, очевидно, используются в некоторых реализациях.Стандарт не хочет делать существующие реализации несоответствующими, если этого можно избежать.

Одной из причин использования набора битов может быть то, что его размер подходит лучше, чем перечисление или целое число.Не все системы даже имеют std::uint32_t.Может быть, bitset<24> там будет работать лучше?

...