Un collègue voulait écrire ceci:
std::string_view strip_whitespace(std::string_view sv);
std::string line = "hello ";
line = strip_whitespace(line);
J'ai dit que le retour string_view
me mettait mal à l'aise a priori , et en plus, le pseudonyme ici me semblait UB.
Je peux dire avec certitude que line = strip_whitespace(line)
dans ce cas est équivalent à line = std::string_view(line.data(), 5)
. Je crois que va appeler string::operator=(const T&) [with T=string_view]
, qui est défini pour être équivalent à line.assign(const T&) [with T=string_view]
, qui est défini pour être équivalent à line.assign(line.data(), 5)
, qui est défini pour faire ceci:
Preconditions: [s, s + n) is a valid range.
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n).
Returns: *this.
Mais cela ne dit pas ce qui se passe quand il y a un alias.
J'ai posé cette question sur le cpplang Slack hier et j'ai obtenu des réponses mitigées. Vous recherchez ici des réponses faisant autorité et / ou une analyse empirique des implémentations de fournisseurs de bibliothèques réelles.
J'ai écrit des cas de test pour string::assign
, vector::assign
, deque::assign
, list::assign
et forward_list::assign
.
- Libc ++ fait fonctionner tous ces cas de test.
- Libstdc ++ les fait tous fonctionner sauf pour
forward_list
, qui segfaults. - Je ne connais pas la bibliothèque de MSVC.
Le segfault dans libstdc ++ me donne l'espoir que c'est UB; mais je vois aussi à la fois libc ++ et libstdc ++ faire de gros efforts pour que cela fonctionne au moins dans les cas courants.
*this
. Mais je ne vois rien pour empêcher la réutilisation du stockage existant, auquel cas cela devient non spécifié, car la sémantique de la copie du stockage n'est pas spécifiée.
assign
exigences de [tab: container.seq.req] .