web-dev-qa-db-fra.com

Différence dans la spécification de la fonction c_str entre C++ 03 et C++ 11

Dans C++ reference of c_str() in std::string, les éléments suivants apparaissent:

Valeur de retour
Pointeur sur le stockage de caractères sous-jacent.
data()[i] == operator[](i) for every i in [0, size()) (jusqu'à C++ 11)
data() + i == &operator[](i) for every i in [0, size()] (depuis C++ 11)

Je ne comprends pas la différence entre les deux, à l'exception de l'augmentation de la plage d'un élément depuis C++ 11.

La première déclaration data()[i] == operator[](i) n'est-elle pas également vraie pour la dernière?

26
Chiel

À l'exception de l'incrément de plage d'un élément depuis C++ 11, il existe encore une grande différence entre:

data()[i] == operator[](i)

et:

data() + i == &operator[](i)

Cette différence principale est l'opérateur & dans les prototypes. 

L'ancien prototype autorisait la création de copy lorsqu'une opération d'écriture était effectuée, car le pointeur renvoyé pouvait pointer vers un autre tampon que celui contenant la chaîne d'origine.

L’autre différence entre les prototypes data()[i] et data() + i n’est pas critique, car ils sont équivalents .


Une différence entre C++ et C++ 11 est que, dans le premier cas, un std::string n'était pas spécifié explicitement par le standard pour savoir s'il aurait ou non un terminateur nul. Dans le dernier cas cependant, cela est spécifié.

En d'autres termes: std :: string sera-t-il toujours terminé par NULL en C++ 11? Oui.

20
gsamaras

Notez la différence entre les crochets de fermeture:

[0, taille ())

[0, taille ()]

Premier correspond à un intervalle exclusif (c'est-à-dire que l'élément à size index n'est pas inclus), tandis que l'autre correspond à un intervalle inclusif (c'est-à-dire que l'élément à size index est inclus) en C++ 11, l'accès au caractère à la position size() est bien défini.

En ce qui concerne la différence entre data()[i] == operator[](i) et data() + i == &operator[](i), le second applique davantage de restrictions à la mise en œuvre potentielle. Dans le premier cas, un pointeur sur le tampon renvoyé par data() peut être différent du pointeur sur le tampon, où une valeur à laquelle la référence renvoyée par operator [] est stockée. Cela peut arriver lorsqu'un nouveau tampon est créé après l'appel de l'opérateur [] non qualifié de const de la chaîne copiée.

9
VTT

Avant C++ 11, il n'était pas spécifié si les données de chaîne étaient terminées par un octet nul ou non. C++ 11 dit qu'il doit avoir une terminaison nulle.

0
Neil Butterworth