web-dev-qa-db-ja.com

C ++ 20の 'char8_t'は以前の 'char'と同じですか?

CPPリファレンス documentation では、

charに気づきました

文字タイプは、UTF-8 8ビットコードユニットを表すのに十分な大きさ(C++ 14以降)

char8_t

uTF-8文字表現のタイプ。UTF-8コード単位(8ビット)を表すのに十分な大きさが必要

それは両方が同じタイプであることを意味しますか?またはchar8_t他の機能がありますか?

35
Pavan Chandaka

char8_tcharと同じではありません。 [basic.fundamental]/9 によるが、unsigned charとまったく同じように動作します。

タイプchar8_­tは、基礎となるタイプがunsigned charである特殊タイプを示します。型char16_­tchar32_­tは、uint_­least16_­tの基になる型がそれぞれuint_­least32_­t<cstdint>.である特殊な型を示します

重点鉱山


標準ではこれを異なる型と呼ぶため、次のようなコードに注意してください

std::cout << std::is_same_v<unsigned char, char8_t>;

0char8_tとして実装されていますが、unsigned char(false)を出力します。これはエイリアスではなく、特殊なタイプだからです。


もう1つ注意すべき点は、charsigned charまたはunsigned charとして実装できることです。つまり、charchar8_tと同じ範囲と表現を持つことは可能ですが、それらはまだ別の型です。 charsigned charunsigned charchar8_tは同じサイズですが、すべて異なるタイプです。

41
NathanOliver

免責事項:私はchar8_tP0482 および P142 の提案の作成者です。

C++ 20では、char8_tは他のすべての型とは異なる型です。 Cの関連する提案 N2231 (これはWG14への更新と再提案が必要です)では、char8_tは既存のunsigned charと同様のtypedefになりますchar16_tおよびchar32_tのtypedef。

C++ 20では、char8_tunsigned charに一致する基本的な表現を持っています。したがって、unsigned charと同じサイズ(少なくとも8ビットですが、それより大きくなる可能性があります)、配置、および整数変換ランクがありますが、エイリアス規則は異なります。

特に、char8_t[basic.lval] p11 のタイプのリストに追加されませんでした。 [basic.life] p6.4[basic.types] p2 、または [basic.types] p4 。つまり、unsigned charとは異なり、別のタイプのオブジェクトの基になるストレージに使用したり、他のタイプのオブジェクトの基になる表現を検査したりすることはできません。つまり、他の型のエイリアスには使用できません。この結果、タイプchar8_tのオブジェクトには、charまたはunsigned charへのポインターを介してアクセスできますが、char8_tへのポインターを使用してcharまたはunsigned charデータ。言い換えると:

reinterpret_cast<const char   *>(u8"text"); // Ok.
reinterpret_cast<const char8_t*>("text");   // Undefined behavior.

これらのプロパティを持つ特殊タイプの動機は次のとおりです。

  1. UTF-8文字データと文字データの区別タイプを、ロケール依存のエンコードまたは個別の指定が必要なエンコードで提供するため。

  2. 通常の文字列リテラルとUTF-8文字列リテラルのオーバーロードを有効にするには(エンコードが異なる場合があるため)。

  3. UTF-8データの署名なしの型を保証するため(charが署名されているか、署名されていないかは、実装で定義されています)。

  4. 非エイリアシングタイプを介してパフォーマンスを向上させるには、オプティマイザは、他の型をエイリアスしない型をより適切に最適化できます。

22
Tom Honermann