---
title: C++20未満でもUTF-8型を使いたかった
tags: 
author: [zbdk](https://www.docswell.com/user/zbdk)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LE143WPYEG.jpg?width=480
description: C++ breaktime 2025/Summerの発表資料です。
published: June 21, 25
canonical: https://www.docswell.com/s/zbdk/ZQR66W-2025-06-21-090322
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LE143WPYEG.jpg)

C++20未満でもUTF-8型
を使いたかった
@zbdk


# Page. 2

![Page Image](https://bcdn.docswell.com/page/GEWXP62172.jpg)

C++の文字列
■ UTF-8文字列を表す型が欲しい
– 今までcharにASCII or SJIS or UTF-8が混在
– SJISとUTF-8を区別したい
■ char8_t型(C++20～)
– 当時コンパイラがC+＋20に対応していなかった
■ C++20までのつなぎとして自前の型を用意した


# Page. 3

![Page Image](https://bcdn.docswell.com/page/47Z6KYDX73.jpg)

UTF-8文字列リテラル
■ u8”text”の表す型
– C++11～C++17
■ const char[N]
– C++20～
■ const char8_t[N]


# Page. 4

![Page Image](https://bcdn.docswell.com/page/YJ62QD1P7V.jpg)

C++20移行
■ マクロを用意してスムーズに移行できるよう用意


# Page. 5

![Page Image](https://bcdn.docswell.com/page/GJ52R34PJ4.jpg)

ちょっとまって
■ これってStrict Aliasingルールに違反してる？
■ Strict Aliasingルール
– 異なる型にキャストする際にユーザー側が守らないと
いけないルール


# Page. 6

![Page Image](https://bcdn.docswell.com/page/LE3KP6G6E5.jpg)

Strict Aliasingルール
■ 本人が自認する型とは異なる型としてアクセスしては
いけない
オレ float
float value
float
int
intとしてアクセス
キャスト
reinterpret_cast&lt;int*&gt;(&amp;value)
逆参照
*


# Page. 7

![Page Image](https://bcdn.docswell.com/page/8ED3LV1M7G.jpg)

今回のケース
■ 文字として使う場合にcharに戻して使っていたのでOK
～C++17
オレ char
charとしてアクセス
u8”text”
char
mychar8_t
const char* msg
キャスト
キャスト
関数引き渡し
const UTF8* msg_u8
do_something(const UTF8*)
※pointer-interconvertibleを満たすべきなのかは調べきれませんでした


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V7P42VQQE8.jpg)

C++20になると？
■ ルール違反していそうだがcharは例外的にアクセス可能
C++20～
charとしてアクセス
const char* msg
char
char8_t
キャスト
オレ char8_t
関数引き渡し
u8”text”
do_something(const UTF8*)


# Page. 9

![Page Image](https://bcdn.docswell.com/page/2JVXDZ5P7Q.jpg)

その後
■ いつの間にかu8stringが生まれていた
– using u8string = std::basic_string&lt;UTF8&gt;;
■ そして最近
– 「Xcodeのバージョン上げたらu8stringがエラーに
なったんですけど」
– 新しいClangさんが「char_traitsに文字型以外の型を入
れんじゃねぇよ」と言うようになった
– さらにXcodeのバージョンを上げたらエラーは出なく
なった


# Page. 10

![Page Image](https://bcdn.docswell.com/page/5EGVY46QEL.jpg)

まさにこれ


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4JQ6MG4WJP.jpg)

おわりに
■ みんなC++20以降を使おう！
■ こんな型作ったよ～、というゆるふわな内容にしようと
思っていたのにどうしてこんな内容に・・・


# Page. 12

![Page Image](https://bcdn.docswell.com/page/K744V5Q171.jpg)

おまけ
スライド作ったけど発表からは省いたやつ


# Page. 13

![Page Image](https://bcdn.docswell.com/page/LJ143WP5JG.jpg)

これは合法
■ Strict Aliasingルールに則った書き方
– charへキャストしてのアクセスはOK
– あるいはmemcpy


# Page. 14

![Page Image](https://bcdn.docswell.com/page/GJWXP62WE2.jpg)

mychar8_tでできないこと
■ 文字列リテラルの連結
– auto* lit = U8_TEXT(“aaa”) U8_TEXT(“bbb”);
■ mychar8_t配列の文字列初期化
– UTF8 arr1[] = U8_TEXT(“arr”);
■ なんでそんなことするんですか？
– UTF8 arr2[] = {UTF8(&#039;a&#039;), UTF8(&#039;r&#039;), UTF8(&#039;r&#039;), UTF8(&#039;\0’)};
■ さすがにこれは提案できなかった
■ arr2の文字たちは「オレmychar8_t」と思って生きている
のにも注意


