Togetter/min.tを安心してお使い頂くためのガイドラインを公開しました。
2018年12月23日

原理主義的に 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
残りを読む(24)

コメント

おろろ @fYe39CoQsPrbZVK 2018年12月23日
文字て概念をリテラルにしようとすんのが間違いでは。イメージ的には画像と同じように先頭に設定情報入れて、そこからバイト列て感じ
4
まひわり @Mahiwari_jpnn 2018年12月23日
UCS2をバイトにマップする時に俺の知らないバイトサイズでいいから1文字という単位で隠蔽しておいてほしいみたいなアレかねえ。BOMとか付けないで。forでぐるぐるCSVを分解したいときとか。
0
元ダルマ @motsu_ad1885 2018年12月23日
C++初心者を名乗る方から全力放出される「素人質問ですが…」感。
2
元ダルマ @motsu_ad1885 2018年12月23日
文字がうねうねしている言語圏とか、一文字に見えても色々組み合わさってるのね…。大変そうだ。
1
さ​ろ​げー​と @surrogatepair 2018年12月23日
Unicodeがパンドラの箱なのは痛いほどよくわかる。しかし、2018年まで放置されていいはずはない。
0
compsci081113 @compsci081113 2018年12月24日
fYe39CoQsPrbZVK よく分からないけど、正にそのような考えが昔っからのchar配列で、それだと様々なところで支障をきたすので、諸々の果てが今回の「はてなブックマーク::Hotentry @hatebu C++標準化委員会、ついに文字とは何かを理解する: char8_t 」に繋がっているのでは?
0
compsci081113 @compsci081113 2018年12月24日
motsu_ad1885 「一文字」を色々な組み合わせから作っているから、ヤヤコシイと読んだのですが、逆でした?
0
アズなんとかさん @as_capabl 2018年12月24日
ByteString型がエンコード情報のない単なるバイト列という扱いで、エンコード込みで抽象化したText型もあるけどByteStringとTextのオーバーロードができず、それぞれにStrict版とLazy版があってやはりオーバーロードできず、さらに「文字のリンクリスト」という実用性ゼロの型が「標準の文字列型」として存在するもんで、文字列関係がカオスになっているHaskellという言語があってだな
0
おろろ @fYe39CoQsPrbZVK 2018年12月24日
compsci081113 charて時点で文字リテラルになってるんですが。何が一緒なん?
0
tgttr @tgttr4 2018年12月24日
Mahiwari_jpnn 一文字とは何か。厳密に定義が困難。
1
ゆーき @yuki073 2018年12月24日
tgttr4 Unicodeの時点で1文字をきちんと定義していればなぁ。
0
順三朗 @junzabroP 2018年12月27日
というかいい加減、UTF-8でもUTF-16でもいいから、内部表現がUnicodeであると確定してる文字列型がほしい。PythonだってすったもんだあってもPython3からUnicodeで一本化したじゃん。
1
frisky @friskymonpetit 2018年12月27日
Unicodeがすべての言語のすべての文字を包含した後、取捨選択があって、真の文字列の在り方がわかるんだと思うのね。Unicodeは「文字とはなんであるか」を探す「プロジェクト」であって、要件の定まった「プロダクト」ではないと思うんだよねぇ。
1
yumetodo @yumetodo 2019年1月5日
yuki073 4通りの定義がされています。
0