Драфт нового стандарта C0x вызывает у меня последнее время все больше вопросов. Такое впечатление, что господа Страуструп, Саттер и компания даже не подчистили проблемы, известные со времен обсуждения предыдущего C98. Вот яркий пример.
Еще в 98-99 годах активно высказывались мнения (упомянутого Саттера), что описание vector<bool> в стандарте С98 содержит внутреннее противоречие – данный контейнер не является стандартным, а также является underspecified.
Еще ДО принятия C98 делались попытки разрешить эту ситуацию, но к сожалению безрезультатно. Как с некой суммой информации об этом (а также, если кто-то подзабыл – в чем собсна проблема) можно ознакомиться вот с этой статьей.
Поскольку в большинстве статей по проблеме, которые я видел, люди пишут что-то вроде
нельзя сделать ссылку на элемент вектора, или получить ссылку из итератора, или выполнить
vector<bool> vb;
...//init vb
bool *b = &vb[0];
и на этом «мысль заканчивается», пойдем немного дальше и попытаемся понять, почему же это так плохо.
Для начала – чем хорош нынешний vector<bool>? Он оптимизирует место, занимаемое контейнером. Когда это полезно? Когда массив очень большой. А какие еще проблемы у нас возникнут при работе с большим массивом, помимо места? Скорость, разумеется. Проблема не в том, что как пишут здесь , «1 Кб никого не парит», а в том что эта оптимизация места оборачивается пессимизацией скорости – не «потенциально», а 100% кинетически, если вы работаете с большими массивами bool, т.е. сохраняете их, копируете, передаете каким-то другим модулям. Благодаря невозможности получить указатели на кусок памяти, занимаемый нужным фрагментом контейнера, для нас закрыта возможность работать через быстрые «старорежимные» rtl-фунции типа memcpy ( или скажем fwrite, который сработает в несколько раз быстрее, чем всякие там ostream_iterator(ofstream_object) ). Т.е. примененная «оптимизация для больших объемов» при работе с оными создаст вам гораздо более грозные проблемы, чем те что она решает. Это известно с 90-х годов, но в Dinkumware STL, которую использует VS 2005, у vector<bool> по-прежнему нет методов получения вожделенного указателя, хотя от рождения есть всякие нестандартные flip, и можно было бы добавить еще. Это означает, что vector<bool> – «политический труп», на который давно махнули рукой, и все рекомендуют его просто игнорировать.
Что же мы видим в драфте нового стандарта (вот его позднейший кусочек про сабж) ? А ничего. Все та же мутная херня, что и была в предыдущем стандарте. Те же пожелания реализовывать vector<bool> с упаковкой в биты. Даже не потрудились переименовать vector<bool> в bit_vector, чтобы люди могли легко получить нормальную, не проксированную реализацию vector<bool>.