2017-01-17 1 views
1

J'utilise un deque dans l'un de mes programmes C++, et je lisais la documentation de insert sur cppreference.com. La plupart d'entre elles ont du sens sauf ce bit:Quel effet "insert" at-il sur les références à deques?

Tous les itérateurs, y compris l'itérateur passé, sont invalidés. Les références sont également invalidées, sauf si pos == begin() ou pos == end(), auquel cas elles ne sont pas invalidées.

Qu'est-ce que cela signifie? Est-ce dire que les références à la deque elle-même sont invalidées, ou des références à ses éléments, ou des références aux itérateurs? Ou quelque chose d'autre entièrement?

est ici un lien de la doc en question: http://en.cppreference.com/w/cpp/container/deque/insert

+3

Références aux éléments. –

+0

@BaummitAugen Comment est-ce possible? Les références C++ ne peuvent pas être modifiées une fois qu'elles ont été attribuées. – Dovahkiin

+0

[Relié] (https://stackoverflow.com/questions/913980/confusion-on-iterators-invalidation-in-deque) –

Répondre

1

A deque est un objet. C'est un conteneur, donc il contient autres objets dans son stockage interne. Ce sont des éléments stockés dans un deque.

Vous pouvez accéder à ces éléments. Accéder à un élément revient à obtenir une référence à partir du conteneur. Si vous le cochez, toutes les méthodes de la section element access renvoient un type reference.

Vous pouvez effectuer une copie de l'élément accédé, mais vous pouvez stocker la référence elle-même. T foo = d.front(); contre T& bar = d.front();. (Let d être un peu std::deque<T>)

Une référence à un deque serait auto& ref_d = &d;. C'est autre chose.

Alors:

1. Quel effet « insérer » ont des références à Deques?

Aucune. les références à d vont bien.

2. Qu'est-ce que cela signifie?

Un deque est conçu de telle manière que insertion au début ou à la fin de celui-ci ne remet pas en cause les références aux éléments que vous pourriez avoir déjà stockés. Bien que si vous insérez au milieu, les éléments peuvent se déplacer en mémoire. Notez que le bar n'est pas touché. Précisément parce qu'il ne peut pas l'être, il est invalidé. La référence (ou l'itérateur) précédemment obtenue n'indique plus rien de significatif, donc le déréférencement est illégal.

3. Est-ce que cela signifie que les références à la table elle-même sont invalidées?

Nope, comme dans 1.

4. ou les références à ses éléments [sont invalidés]?

Oui, comme dans 2.

5. ou les références aux itérateurs [sont invalidées]?

Vous semblez à nouveau confondre quoi quoi. Une référence à un itérateur serait std::deque<T>::iterator& iter_ref;, si vous obtenez un itérateur d'un deque. Par exemple. auto iter = d.begin(); et faire une référence à iter_ref = &iter;, un insert ne fait pas *iter_ref illégale, il invalide l'itérateur, donc *iter est illégale (ou **ref_iter). Remarque: Je ne dis pas que quelque chose comme std::deque<T>& ref_d ou std::deque<T>::iterator& iter_ref a un sens, mais c'est une signification sémantique de "référence à un deque" et "référence à un interacteur".

+0

Donc, si je comprends bien ... si vous appelez insert sur une position autre que l'avant ou la fin, alors les itérateurs peuvent être invalidés, mais l'insertion à l'avant ou à la fin préserve la validité des itérateurs? – Dovahkiin

+0

Exactement. Voici ce que dit votre citation: "* Tous les itérateurs, y compris l'itérateur du passé, sont invalidés, sauf si' pos == begin() 'ou' pos == end() ', dans lequel cas, ils ne sont pas invalidés. * "Vous venez d'arriver avec des termes supplémentaires de" référence à deque "et" référence à l'itérateur "dans votre question pour une raison quelconque, et est devenu confus. – luk32

+0

Mais toute référence à des éléments qui ont été créés avant l'appel de 'insert' devrait toujours être une référence valide, correct? – Dovahkiin