Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(type_traits): trivially copyableの定義が変更されたのに追従 #768

Merged
merged 16 commits into from
Jun 24, 2020

Conversation

yumetodo
Copy link
Member

@yumetodo yumetodo commented Jun 15, 2020

CWG issue 1734. Nontrivial deleted copy functions
https://wg21.cmeerw.net/cwg/issue1734
C++初心者に贈る強そうな人からC++のclassに関連する謎な用語を使われたときにみるもの: trivialとか - Qiita
https://qiita.com/yumetodo/items/424cc4d15de4edad436a
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved

### 注意

トリビアルコピー可能の定義はかつては以下の全ての条件を満たすことを要求していた。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「かつて」と言うとあいまいなので、「問題が報告された2013年8月時点までは」とかですかね。

- 非トリビアルなコピーコンストラクタを持っていないこと
- 非トリビアルなムーブコンストラクタを持っていないこと
- 非トリビアルなコピー代入演算子を持っていないこと
- 非トリビアルなムーブ代入演算子を持っていないこと
- トリビアルなデストラクタを持っていること

トリビアル(trivial)な特殊関数(コンストラクタ、代入演算子、デストラクタ)とは、「ユーザー定義されない特殊関数」のことを意味する。

しかし、デストラクタが削除されていてもトリビアルコピー可能となる問題があった。[CWG issue 1734](https://wg21.cmeerw.net/cwg/issue1734)によって定義が見直された。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「この仕様修正はC++17の規格に適用されたが、この問題が発見された以降の標準ライブラリ実装では対応している可能性がある。」
とかも足しておくといいですかね。
このへんの書き方の統一は今後考える必要はありますが…。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defectなのでどのISOで発行されたC++規格書に対してか?はあまり意味を持たないと
標準C++の欠陥解決は、過去のバージョンに遡って適用される - Faith and Brave - C++で遊ぼう
にかかれていたので、それに従ってC++17の規格に適用された話も省いちゃったんですが、やっぱり省かないほうがいいんでしょうか?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

過去に遡るのも限度があるので、2013年に報告されたから少なくともC++11までは遡れないのですよね。なので、いつ判明したのかと、cpprefjpとしてどの規格に対応しているのかは書いておいたほうがほかの編集者がそれを見たときもわかりやすいのではないかと思います。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

たとえばC++17規格がでて最初のコンパイラ対応のリリースバージョンには直っているようなdefectだったら、バージョン注記の必要なくcpprefjp上の仕様を直してよいかと思います。
そういう素直な対応ができない場合は、実装のずれなどもあるので、できる限りの情報は必要かと思います。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2013年に報告されたから少なくともC++11までは遡れないのですよね。

そうなんですか?知らなかった。

statusをみるとcd4となっていて、

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html
CD4: A DR/DRWP or Accepted/WP issue not resolved in C++14 but included in the Committee Draft advanced for balloting at the June, 2014 WG21 meeting.

という意味らしいんですが、じゃあC++14には遡及できるでしょうかね・・・?

遡及して適用している実装が確認できればいいんでしょうか・・・?

https://groups.google.com/a/isocpp.org/d/msg/std-discussion/ilmqKwKPETs/u4Ty0PuoBwAJ

The model used by cppreference is like that of implementers: we include in "C++xy" patches to defects in the C++xy standard as published. It is not useful for us to, say, claim that vector v; is ill-formed before C++17, because the would be parsed as a header-name preprocessing token according to the published standards prior to the resolution of CWG 2000.

Since C++11 CWG has generally used a special designation for defect reports in its issue lists, but it doesn't say how far back the DRs reach. LWG doesn't use a special designation at all :( In such cases we examine the behavior of implementations to see if the resolution should be treated as a defect report and if so for which standard revisions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++14の規格には適用できそうですね。
実装はさかのぼって調査が大変だと思うので「x年以降対応している可能性がある」と書いておけばひとまずよいかと思います。

@@ -26,16 +26,41 @@ namespace std {
## 効果
`is_trivially_copyable`は、`T`がトリビアルコピー可能な型であるならば[`true_type`](true_type.md)から派生し、そうでなければ[`false_type`](false_type.md)から派生する。

ユーザーが関数を宣言したとき、`user-declared`であると言える。`= default`/`= delete`指定されたものも含む。

`user-provided`とは、`user-declared`なものから`= default`/`= delete`指定されたものを除くものである。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`user-provided`とは、`user-declared`なものから`= default`/`= delete`指定されたものを除くものである
`user-provided`とは、`= default`/`= delete`指定されたものを含まない、ユーザーによる関数宣言である

日本語の意味がとりにくかったです。

user-declaredの導入が必要なくなる修正案ですが、残すなら「user-providedとは、user-declaredな関数宣言のうち、= default/= delete指定されたものを含まないユーザーによる関数宣言である。」とかですかね。

reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
「トリビアルコピー可能な型」とは、「`std::memcpy()`可能な型である」と言い換えることもできる。これに分類される型は、以下の全ての条件を満たす必要がある:

- 全てのコピー/ムーブ コンストラクタ/代入演算子はtrivialもしくは`= delete`指定されている
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この一文ですが、C++17だと「where each copy constructor, move constructor, copy assignment operator, and move assignment operator (15.8, 16.5.3) is either deleted or trivial,」なので対応していて、C++20だと「that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator (11.4.3, 11.4.4.2, 11.4.5),」で「少なくとも1つは適格」になっていますね。
経緯を調べないと…。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++20のほうは私も見てなかったです。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cplusplus/draft@98c2c56
commit見てきたけどさっぱりわかりません。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept絡みで、適格な特殊メンバ関数であるかどうかが重要になってくるらしい

yumetodo and others added 3 commits June 16, 2020 19:16
Co-authored-by: Akira Takahashi <faithandbrave@gmail.com>
Co-authored-by: Akira Takahashi <faithandbrave@gmail.com>
@yumetodo
Copy link
Member Author

やや指摘とは違う修正方法ですがこんな感じでどうでしょうか?

@yumetodo
Copy link
Member Author

C++20での差分ですが、C++17のところに書くのはわかりづらくなりそうです。まだ書いてませんが、

  1. C++20時点の定義
  2. C++17 or cwg issue 1734適用後の定義
  3. cwg issue 1734適用前の定義

という3つの節に分けて書こうかと考えています。

@faithandbrave
Copy link
Member

user-providedとは、= default/= delete指定されたものを含まない、user-declaredなものである。

んー、言いたいことはわかりますが、遠回りなのと「なものである」が前文を読まないと意味と特定できないので読み取りにくくはあります。
正式な仕様書ならuser-declaredの導入は必要かもしれませんが、このページを説明するためにはユーザーにとって必要な情報ではないように思います。

@yumetodo
Copy link
Member Author

yumetodo commented Jun 18, 2020

C++20の内容も記述したのでもう一度レビューお願いします。特に新しく追加した例は提案文章のものをとりあえずコンパイルできるようにしただけで、私がconceptをきちんと理解していないので間違えている可能性があります。

@yumetodo
Copy link
Member Author

例で説明なしに `TriviallyCopyConstructible` とかが出てきているけど、 `a<T> && b<T>` が `a<T>` より強い制約となりうるのは `a` と `b` が両方 concept の場合であって、単なる定数式の場合は ambiguous になるはず。https://t.co/adn8PvpQL8

— 白山風露 (@kazatsuyu) June 18, 2020

@yumetodo
Copy link
Member Author

ああ、proposalから持ってきたのか。だとすると、コンセプト名の規約はsnake_caseに変更されているのでそうすべき。あとtrivially_copy_constructible コンセプトは現状のドラフトには入っていないように見える

— 白山風露 (@kazatsuyu) June 18, 2020

reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
reference/type_traits/is_trivially_copyable.md Outdated Show resolved Hide resolved
@onihusube
Copy link
Member

cpprefjpではwell-formedの訳も適格となっていますが、この場合の適格はeligibleですよね?

確かにどっちも適格なのですが、前者は適正や合法みたいな意味で、後者は適任や資格があるみたいな意味になると思います。適格な訳は思いつかないのですが、同じ言葉を当てて良いのでしょうか?

@yumetodo
Copy link
Member Author

yumetodo commented Jun 19, 2020

eligibleとwell-formedでは確かに意味合いが違うのに訳が同じなのは問題ですね・・・。しかしやはり適切な訳語が思い当たりません。well-formedを適格と訳してるのは多分JIS規格書から来てると思うのですが。

yumetodo and others added 4 commits June 19, 2020 19:41
Co-authored-by: onihusube <44743040+onihusube@users.noreply.github.com>
Co-authored-by: onihusube <44743040+onihusube@users.noreply.github.com>
対象となるクラスの非静的メンバ変数及び全ての基底クラスもトリビアルコピー可能でなければならない
@yumetodo
Copy link
Member Author

https://qiitadon.com/@7of9/104370486660492901
@yumetodo

適合する特殊メンバ関数
ですかね

適格は違う気はします

注意
自分は日本語がだめかもしれないので、あまり信用しない方がいいかもですが

@onihusube
Copy link
Member

個人的には適合もしっくりこないのですが、他に何も思いつかないのでなんとも・・・

@akinomyoga
Copy link
Member

適合は conforming のJIS訳と被りますね。ここでの意味 (eligible special member function [special]/6) を考えたら "有効な" とか "利用可能な" とか…?

Co-authored-by: onihusube <44743040+onihusube@users.noreply.github.com>
@yumetodo
Copy link
Member Author

適合は conforming のJIS訳と被りますね。

あやや

"有効な" とか "利用可能な" とか…?

有効な、のほうが近いかな?

もう一晩くらい訳語は寝かせたほうがよさそう。

@yumetodo
Copy link
Member Author

https://fedibird.com/@mmasuda/104373273858130558
@yumetodo アメフトの世界だとeligible は「有資格」というのがルールブック上の定訳になっていますね。

Eligible receiver = 有資格レシーバー
ineligible receiver downfield =無資格レシーバーのダウンフィールドへの進入
というのが日本アメフト協会公式ルールの用語表現。

@yumetodo
Copy link
Member Author

「有資格」、というより「資格を持つ」なら違和感が少ないかもしれないと思いますがどうでしょうか?

@akinomyoga
Copy link
Member

対象が人じゃないので意味的には「資格のある」よりも「条件を満たした」なのかなと思いますが「条件を満たした特殊メンバ関数」だと一まとまりの用語という感じが薄いですね。「条件を満たす」で類語を探しても簡潔な物は見つからず。検索するとフィギュアスケートでは eligible は単に片仮名にして「エリジブル」らしき情報があります。まあ、これまで出た中では「有資格」または「資格のある」でいいかなって気がします。

ところで trivially をトリビアルに訳すのが気になって検索してみたら cpprefjp 内で訳が「自明」と「トリビアル」に割れています ("トリビアル" site:cpprefjp.github.io & "自明" site:cpprefjp.github.io)。しかも is_trivial - cpprefjp C++日本語リファレンス は一つのページ内で二つが混在しています:

型Tがトリビアル型か調べる。自明型は、…

@yumetodo
Copy link
Member Author

yumetodo commented Jun 20, 2020

自明という単語が自明じゃないので自明を採用したくないという思いです(?)

・・・実際問題どちらに揃えるほうがわかりやすいんだろうか。

@akinomyoga
Copy link
Member

・・・実際問題どちらに揃えるほうがわかりやすいんだろうか。

それ、わからないですよね。多分「トリビアル」と言って通じる層と「自明」と言って通じる層は一致しますよね。どちらも数学とか理系の議論に触れたことのある人で。英語の文献まで行かない理系学生だと「自明」の方が通りが良いかも。でもこういう応用的な「自明」の使い方をするのは英語の文献まで行く層の気もします。

全く新しい語として受け入れる層からすると、今度は片仮名の方が憶えやすいか・漢字の方が憶えやすいかという話になりますが、これも人によります。僕は断然漢字の未知の語の方が (漢字の意味に何となくこじつけて) 馴染みやすいのですが、人によっては片仮名の方が憶えやすかったりするらしいです (純粋な語感で対応させているのでしょうか)。

まあ、どちらでも良いのですが揃えた方が良い気がします。取り敢えず少なくとも、is_trivial - cpprefjp C++日本語リファレンス のは。

@yumetodo
Copy link
Member Author

yumetodo commented Jun 24, 2020

eligibleの訳語としてはとりあえず「資格のある」を当てることとし編集しました。trivialの訳語が揺れている件は本PRの範疇を外れるので #776 を立てました

その他問題がなければmergeお願いします。

@onihusube onihusube merged commit 976b480 into master Jun 24, 2020
@faithandbrave faithandbrave deleted the fix/trivially_copyable_def branch June 25, 2020 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants