web-dev-qa-db-ja.com

C ++ 20、u8、char8_t、およびstd :: string

C++ 11は、UTF-8リテラルのu8プレフィックスをもたらしました。数年前はかなりクールだと思い、コードに次のような要素を追加しました。

std::string myString = u8"●";

これはすべてうまく機能しますが、C++ 20で問題が発生します。u8がchar8_t *を作成し、これがcharだけを使用するstd :: stringと互換性がないため、コンパイルはできなくなったようです。

新しいutf8stringを作成する必要がありますか?標準のstd :: stringと実際には一致しないより明示的な型があるC++ 20の世界でこの種のことを行うための一貫した正しい方法は何ですか?

26
M2tM

@lubgrの回答に加えて、論文 char8_t下位互換性の修正(P1423) は、std::stringchar8_t文字配列。

基本的には、u8 char配列を「通常の」char配列に変換して、C++ 17以前と同じ動作を実現するには、もう少し明示的にする必要があります。このペーパーでは、これを行うためのさまざまな方法について説明します。

ユースケースに適合する最も単純な(ただし、オーバーロードを追加しない限り、オーバーヘッドが完全にゼロではない)メソッドはおそらく最後のメソッドです。つまり、明示的な変換関数を導入します。

std::string from_u8string(const std::string &s) {
  return s;
}
std::string from_u8string(std::string &&s) {
  return std::move(s);
}
#if defined(__cpp_lib_char8_t)
std::string from_u8string(const std::u8string &s) {
  return std::string(s.begin(), s.end());
}
#endif
15
Fabio Fracassi

新しいutf8stringを作成する必要がありますか?

いいえ、すでにあります。 P0482char8_tを提案するだけでなく、std::basic_stringという名前のchar8_t文字タイプのstd::u8stringという新しい特殊化も提案します。したがって、これはトランクからのclangおよびlibc++ですでにコンパイルされています。

const std::u8string str = u8"●";

std::string-リテラルの改行からのu8構成が壊れているという事実は残念です。提案から:

この提案では、非推奨のインターフェースを保持する以外の下位互換性機能は指定していません。著者はそのような機能が必要であると信じていますが、そのような機能の単一のセットはこの提案の目標を不必要に妥協するでしょう。むしろ、実装は、よりきめの細かい互換性機能を有効にするオプションを提供することが期待されています。

しかし、私は上記のような初期化のほとんどがgrep- ableであるか、いくつかの自動clangツールの修正の対象となると思います。

14
lubgr