Коллега хотел написать это:
std::string_view strip_whitespace(std::string_view sv);
std::string line = "hello ";
line = strip_whitespace(line);
Я сказал, что возвращение string_view
сделало меня априори непростым , и, кроме того, псевдоним здесь выглядел как UB для меня.
Я могу с уверенностью сказать, что line = strip_whitespace(line)
в этом случае эквивалентно line = std::string_view(line.data(), 5)
. Я считаю, что вызов будет string::operator=(const T&) [with T=string_view]
, который определен, чтобы быть эквивалентным line.assign(const T&) [with T=string_view]
, который определен, чтобы быть эквивалентным line.assign(line.data(), 5)
, который определен для этого:
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.
Но это не говорит о том, что происходит, когда есть псевдоним.
Я задал этот вопрос вчера на cpplang Slack и получил смешанные ответы. Здесь вы найдете ответы на самые серьезные вопросы и / или эмпирический анализ реализаций реальных поставщиков библиотек.
Я написал тестовые случаи для string::assign
, vector::assign
, deque::assign
, list::assign
, и forward_list::assign
.
- Libc ++ заставляет все эти тестовые случаи работать.
- Libstdc ++ заставляет их все работать, за исключением
forward_list
, что segfaults. - Я не знаю о библиотеке MSVC.
Segfault в libstdc ++ дает мне надежду, что это UB; но я также вижу, что и libc ++, и libstdc ++ будут прилагать большие усилия, чтобы сделать это, по крайней мере, в обычных случаях.
*this
. Но я ничего не вижу, чтобы предотвратить повторное использование существующего хранилища, и в этом случае это становится неопределенным, поскольку семантика перезаписи хранилища не определена.
assign
в [tab: container.seq.req] .