Резервирование мощности для специализации шаблона STD vector <bool> - PullRequest
0 голосов
/ 25 мая 2018

Я смотрю на экономически узкую специализацию std::vector для типа bool, т. Е. std::vector<bool>.Следующий MWE создает объект и резервирует память для него:

#include <iostream>
#include <vector>

int main() {
  size_t nn{10};
  std::vector<bool> theVector{};
  theVector.reserve(nn);
}

Однако, когда я компилирую этот MWE с:

$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

, выполняя это:

$ g++ -std=c++14 -g mwe.cpp -o mwe

и затем выполнить отладку, используя:

$ gdb --version
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1

Я получаю следующий вывод:

Breakpoint 1, main () at mwe.cpp:6
6     size_t nn{10};
(gdb) n
7     std::vector<bool> theVector{};
(gdb) n
8     theVector.reserve(nn);
(gdb) p theVector 
$1 = std::vector<bool> of length 0, capacity 0
(gdb) n
7     std::vector<bool> theVector{};
(gdb) p theVector 
$2 = std::vector<bool> of length 0, capacity 64
(gdb) 

Почему я получаю емкость 64, если я указал общую емкость 10?

Предыдущее исследование привело меня к чтению об этой специализации шаблона.Из cppreference.com я узнал, что для того, чтобы быть эффективным, этот шаблон может: для экономии места он:

  1. не обязательно хранит свои элементы как непрерывныемассив (т. е. &v[0] + n != &v[n])
  2. Предлагает класс std::vector<bool>::reference как метод доступа к отдельным битам.В частности, объекты этого класса возвращаются значением operator[].
  3. Не использует std::allocator_traits::construct для создания битовых значений.
  4. Не гарантирует, что разные элементы в одном и том же контейнере могутмогут быть изменены одновременно разными потоками.

И все же мне не удается понять, как эти меры могут привести к поведению, с которым я сталкиваюсь.

1 Ответ

0 голосов
/ 25 мая 2018

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

Тот факт, что вы видите это только для std::vector<bool>, предполагает, что это связано с тем, какэлементы хранятся внутри.

Как вы уже узнали, std::vector<bool> обычно специализируется на эффективном хранении своих элементов в виде битов, упаковывая их в некоторый больший тип.

Таким образом,фактическая емкость всегда будет кратна числу битов, которые могут быть сохранены в более крупном типе.В этом случае указанный тип имеет ширину 64 бита, возможно, какое-то целое число без знака 64-разрядное.

...