原理主義的に C++ の文字列の扱いを根本から変えるにはどうするべきか

文字型の列として文字列型が表せるというのは幻想であるが,しかしその幻想は歴史という重みを伴って現にそこに存在する.
27
はてなブックマーク::Hotentry @hatebu

C++標準化委員会、ついに文字とは何かを理解する: char8_t - Qiita qiita.com/yumetodo/items… b.hatena.ne.jp/entry/https://…

2018-12-22 23:47:08
Akso de la Malbono @Cryolite

C++ 初心者なのですが,仮に C++ に UTF-8 の code unit を保持する型を別個の新しい型として追加するとした場合,この型の invariants は何で,その invariants はどう保証されるんです?

2018-12-23 10:16:10
Akso de la Malbono @Cryolite

「UTF-8文字列である」というinvariantsは文字列のレベルで表現するべきで,「UTF-8のcode unitである」というinvariantsとして補償すべきものがほとんど何もないように思われるので,焦点はUTF-8文字列型をどう実装すべきかであり,UTF-8のcode unitをどう実装すべきかではないように思われる.

2018-12-23 10:25:53
若年寄(もう若くない) @kikairoya

UTF-8文字列を表現する型が無い(std::basic_string<char8_t>では保証できない)以上char8_tだけ入っても邪魔

2018-12-23 11:10:09
若年寄(もう若くない) @kikairoya

char16_t/char32_tはwchar_tのサイズが実装依存だから仕方なしな感じ

2018-12-23 11:12:35
若年寄(もう若くない) @kikairoya

そもそも標準でMBCSをまともに扱えないのにUTF-8を仮定した型なんか作ってどう使わせるつもりなの

2018-12-23 11:22:51
Akso de la Malbono @Cryolite

@kikairoya char16_t と char32_t は uint(_least)16_t と uint(_least)32_t の typedef で良かったのではないか説.

2018-12-23 11:23:15
若年寄(もう若くない) @kikairoya

@Cryolite typedefはちょっと。。。あとuint{16,32}_tって必須じゃないんじゃなかったっけ

2018-12-23 11:26:02
Akso de la Malbono @Cryolite

@kikairoya uint{16,32}_t は「最低{16,32}ビットを保持できるとある整数型の typedef」のつもりで使った. typedef ダメですか?

2018-12-23 11:29:38
若年寄(もう若くない) @kikairoya

@Cryolite 困る。すぐに思いつくのはvector<typedefed_char16_t>をシリアライズ(あるいは単にto_string)するとき

2018-12-23 11:33:45
Akso de la Malbono @Cryolite

@kikairoya 何が困るのか良く分からない.

2018-12-23 11:36:41
若年寄(もう若くない) @kikairoya

@Cryolite 文字のシーケンスと整数のシーケンスは全く違う(少くともserdesや画面表示の面では)。実際問題wchar_tがunsigned shortのままだったらwstringstreamとかは使いものにならかったはず

2018-12-23 11:41:11
Akso de la Malbono @Cryolite

@kikairoya 私は,「最低{16,32}ビットを保持できる型のシーケンスである」は「UTF-{16,32} の文字列である」とは断じて異なるという立場なんですが, vector<char{16,32}_t> に「最低{16,32}ビットを保持できる型のシーケンスの型である」以上の何かを期待するということですか?

2018-12-23 11:54:14
若年寄(もう若くない) @kikairoya

@Cryolite {16,32}ビットを構成単位とする文字のシーケンスであることを期待する(実用上はUTF-{16,32}となるがそれに限らない)。charとunsigned/signed charが、wchar_tとunsigned shortがそれぞれ別物なので。

2018-12-23 11:57:36
若年寄(もう若くない) @kikairoya

@Cryolite 別の観点では、文字列リテラルの型が組み込み型の配列である以上、整数列と文字列の要素型は別物であるべき

2018-12-23 12:00:15
Akso de la Malbono @Cryolite

@kikairoya つまり, char{16,32}_t を「少なくとも{16,32}ビットを保持できる型であり,そのシーケンスを,整数のシーケンスとは区別できる,文字のシーケンスとして解釈すべき型」として期待するということ?

2018-12-23 12:03:57
Akso de la Malbono @Cryolite

@kikairoya 私は,整数列の型と文字列の型は別物であるべきだが,整数列と文字列の要素型は別物であるべきなのかどうかが理解できない.

2018-12-23 12:05:27
Akso de la Malbono @Cryolite

@kikairoya 私は,(現状の C++ がどうであれ) UTF-{8,16,32} の文字列を表現する型がまず存在し,その型のオブジェクトが{8,16,32}ビット以上を保持できる型のシーケンスとしても解釈できる,とすべきだという立場です.

2018-12-23 12:08:23
若年寄(もう若くない) @kikairoya

@Cryolite それでは operator <<(basic_ostream<T> &, uint16_t) を用意できないし、あるいは operator <<(ostream &, const char *) を用意すべきではなかった、ということ?

2018-12-23 12:17:12
Akso de la Malbono @Cryolite

@kikairoya UTF-{8,16,32} の code unit を表す型が, typedef ではなく組み込みの整数型と区別される型として新たに定義されている場合,その型のオブジェクトに対して operator<< がユーザレベルに暴露されているのはおかしい,という立場になります.

2018-12-23 12:21:26
若年寄(もう若くない) @kikairoya

@Cryolite ごめんちょっとよくわからない。たとえばwchar_t(size=2)についてop<<(basic_ostream<wchar_t> &, wchar_t)とop<<(O &, uint16_t)とop<<(O &, const wchar_t *)はどうあるべき? (あとぼくはUTF-{16,32}を期待するchar{16,32}_tが必要、ではなくwchar_tの幅指定版が必要という立場)

2018-12-23 12:32:36
Akso de la Malbono @Cryolite

@kikairoya 現状の C++ を無視して原理主義が許されるならば, op<<(O &, wchar_t) と op<<(O &, const wchar_t *) を削除して op<<(O &, wstring const &) および wstring の slice に対する op<< だけを許す.さらには wchar_t を期待する文字エンコードの code point を保持できる整数型の typedef とする.

2018-12-23 12:39:44
若年寄(もう若くない) @kikairoya

@Cryolite その場合 L"hoge" の型は? os << L"hoge" の結果は?

2018-12-23 12:41:17