Я смотрю на экономически узкую специализацию 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 я узнал, что для того, чтобы быть эффективным, этот шаблон может: для экономии места он:
- не обязательно хранит свои элементы как непрерывныемассив (т. е.
&v[0] + n != &v[n]
) - Предлагает класс
std::vector<bool>::reference
как метод доступа к отдельным битам.В частности, объекты этого класса возвращаются значением operator[]
. - Не использует
std::allocator_traits::construct
для создания битовых значений. - Не гарантирует, что разные элементы в одном и том же контейнере могутмогут быть изменены одновременно разными потоками.
И все же мне не удается понять, как эти меры могут привести к поведению, с которым я сталкиваюсь.