同僚はこれを書きたかった:
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
、segfaultを実行するを除き、すべてを動作させます。 - MSVCのライブラリについて知りません。
libstdc ++のsegfaultは、これがUBであることを期待しています。しかし、少なくとも一般的なケースでは、libc ++とlibstdc ++の両方がこれを機能させるために多大な努力をしていることもわかります。
*this
。しかし、既存のストレージの再利用を妨げるものは何もありません。その場合、ストレージのコピーオーバーのセマンティクスが指定されていないため、これは指定されません。
assign
、[tab:container.seq.req]の要件の前提条件違反のため、それは確かにUB です。