Почему разные векторные элементы<bool> имеют один и тот же адрес?

Я определил следующий класс.

class STTreeNode
{
public:
    int ind;
    int parentInd;  
    std::vector<int> childInds;

    int numTrain;
    std::vector<bool> isInfluenced;

    STTreeNode(int ind, int parentInd, int numTrain);
};

STTreeNode::STTreeNode(int ind, int parentInd, int numTrain) {
    this->ind = ind;
    this->parentInd = parentInd;
    this->numTrain = numTrain;
}

и я выполнил следующий фрагмент кода.

STTreeNode *a = new STTreeNode(3, 4, 5);
a->childInds.push_back(20);
a->childInds.push_back(30);
a->isInfluenced.push_back(true);
a->isInfluenced.push_back(false);

for (int i = 0; i < a->childInds.size(); i++)
    std::cout << &(a->childInds[i]) << " ";
std::cout << std::endl;
for (int i = 0; i < a->isInfluenced.size(); i++)
    std::cout << &(a->isInfluenced[i]) << " ";
std::cout << std::endl;

Вывод был

0000020351C18520 0000020351C18524
00000083540FFC60 00000083540FFC60

Я очень смущен этим. Почему два элемента в a->childInd имеют последовательные адреса (как и ожидалось), а два элемента в a->isInfluenced, кажется, имеют один и тот же адрес?

Обновление:

Из комментариев я понимаю, что это связано с разницей между vector<bool> и другими vector. Существуют ли какие-либо особые случаи с vector, о которых мне следует знать, или же vector<bool> - единственный, на который мне нужно обратить внимание?

Ответы

Ответ 1

Они не Ну, они делают & hellip;

vector<bool> не похож на другие векторы.

К элементам vector<bool> нельзя напрямую получить доступ, как это, потому что они/могут быть меньше байта, который является "разрешением" адресов в C++. Так много битов/элементов упакованы в одну область памяти на вашем компьютере. Но это не то, почему вы получаете эти результаты.

Вы как бы наблюдаете адрес временного. Это временный прокси-объект, который обеспечивает изменяемый доступ к одному биту в вашей коллекции.

Я говорю "вроде", потому что вы даже не берете адрес; указанный прокси-объект имеет operator&, который в некоторых реализациях дает вам то, что называется "битовым итератором".

Здесь Говард Хиннант на vector<bool>.

А пока, работая с vector<bool>, выучите то, что вы знаете о векторах. 😜


Есть ли какие-то особые случаи, связанные с vector, о которых мне следует знать, или же vector<bool> - единственный, на который мне нужно обратить внимание?

vector<bool> единственный.

Ответ 2

std::vector<bool>::operator[] не возвращает bool&, как вы можете ожидать от нормальных векторов, он возвращает std::vector<bool>::reference.

std::vector<bool>::reference является прокси-объектом, содержащим информацию о том, на какой бит он ссылается. Используя эту информацию, он поддерживает несколько операций, чтобы заставить его почти вести себя как bool&. std::vector & lt; bool & gt; :: ссылка на cppreference.com

Когда вы делаете &(a->childInds[i]), вы берете адрес объекта r-значения std::vector<bool>::reference. В вашем случае компилятор повторно использует память при втором вызове оператора [] и поэтому печатает тот же адрес.

Это единственная специализация std::vector.