Un collega voleva scrivere questo:
std::string_view strip_whitespace(std::string_view sv);
std::string line = "hello ";
line = strip_whitespace(line);
Ho detto che il ritorno string_view
mi rendeva inquieto a priori e, inoltre, l'alias qui mi sembrava UB.
Posso affermare con certezza che line = strip_whitespace(line)
in questo caso equivale a line = std::string_view(line.data(), 5)
. Credo che chiamerà string::operator=(const T&) [with T=string_view]
, che è definito come equivalente line.assign(const T&) [with T=string_view]
, che è definito come equivalente line.assign(line.data(), 5)
, che è definito per fare questo:
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.
Ma questo non dice cosa succede quando c'è un aliasing.
Ieri ho fatto questa domanda su cpplang Slack e ho ottenuto risposte contrastanti. Alla ricerca di risposte autorevoli qui e / o analisi empiriche delle implementazioni dei veri venditori di biblioteche.
Ho scritto casi di test per string::assign
, vector::assign
, deque::assign
, list::assign
, e forward_list::assign
.
- Libc ++ fa funzionare tutti questi casi di test.
- Libstdc ++ li fa funzionare tutti tranne
forward_list
, che segfault. - Non conosco la biblioteca di MSVC.
Il segfault in libstdc ++ mi fa sperare che questo sia UB; ma vedo anche che libc ++ e libstdc ++ stanno facendo un grande sforzo per farlo funzionare almeno nei casi comuni.
*this
. Ma non vedo nulla che impedisca il riutilizzo della memoria esistente, nel qual caso ciò non è specificato, poiché la semantica del sovrascrittura della memoria non è specificata.
assign
requisiti in [tab: container.seq.req] .