Współpracownik chciał to napisać:
std::string_view strip_whitespace(std::string_view sv);
std::string line = "hello ";
line = strip_whitespace(line);
Powiedziałem, że powrót string_view
sprawił, że poczułem niepokój a priori , a ponadto aliasing tutaj wyglądał dla mnie jak UB.
Mogę z całą pewnością stwierdzić, że line = strip_whitespace(line)
w tym przypadku jest to odpowiednik line = std::string_view(line.data(), 5)
. Wierzę, że zadzwoni string::operator=(const T&) [with T=string_view]
, która jest zdefiniowana jako równoważna line.assign(const T&) [with T=string_view]
, która jest zdefiniowana jako równoważna line.assign(line.data(), 5)
, która jest zdefiniowana w tym celu:
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.
Ale to nie mówi, co się stanie, gdy pojawi się aliasing.
Zadałem to pytanie wczoraj na cpplang Slack i otrzymałem mieszane odpowiedzi. Poszukuję tutaj autorytatywnych odpowiedzi i / lub analizy empirycznej implementacji prawdziwych dostawców bibliotek.
Pisałem przypadków testowych na string::assign
, vector::assign
, deque::assign
, list::assign
, i forward_list::assign
.
- Libc ++ sprawia, że wszystkie te przypadki testowe działają.
- Libstdc ++ sprawia, że wszystkie działają, z wyjątkiem tego
forward_list
, co segfault. - Nie wiem o bibliotece MSVC.
Segfault w libstdc ++ daje mi nadzieję, że jest to UB; ale widzę też, że zarówno libc ++, jak i libstdc ++ wkładają wiele wysiłku, aby to zadziałało przynajmniej w typowych przypadkach.
*this
. Ale nie widzę nic, co mogłoby uniemożliwić ponowne wykorzystanie istniejącej pamięci, w którym to przypadku nie jest to określone, ponieważ semantyka kopiowania pamięci nie jest określona.
assign
w [tab: container.seq.req] .