Un compañero de trabajo quería escribir esto:
std::string_view strip_whitespace(std::string_view sv);
std::string line = "hello ";
line = strip_whitespace(line);
Dije que regresar string_view
me inquietaba a priori y, además, el alias aquí me parecía UB.
Puedo decir con certeza que line = strip_whitespace(line)
en este caso es equivalente a line = std::string_view(line.data(), 5)
. Creo que llamará string::operator=(const T&) [with T=string_view]
, que se define como equivalente a line.assign(const T&) [with T=string_view]
, que se define como equivalente a line.assign(line.data(), 5)
, que se define para hacer esto:
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.
Pero esto no dice qué sucede cuando hay alias.
Ayer hice esta pregunta en el cpplang Slack y obtuve respuestas mixtas. Buscando respuestas súper autorizadas aquí, y / o análisis empírico de implementaciones de vendedores de bibliotecas reales.
Escribí casos de prueba para string::assign
, vector::assign
, deque::assign
, list::assign
, y forward_list::assign
.
- Libc ++ hace que todos estos casos de prueba funcionen.
- Libstdc ++ hace que todos funcionen, excepto que
forward_list
, por defecto. - No sé sobre la biblioteca de MSVC.
La segfault en libstdc ++ me da la esperanza de que esto sea UB; pero también veo que tanto libc ++ como libstdc ++ están haciendo un gran esfuerzo para que esto funcione al menos en los casos comunes.
*this
. Pero no veo nada para evitar que el almacenamiento existente se reutilice, en cuyo caso esto no se especifica, ya que la semántica de copiar el almacenamiento no está especificada.
assign
requisitos en [tab: container.seq.req] .