Skip to content

141. Linked List Cycle#12

Open
ryosuketc wants to merge 2 commits intomainfrom
141_linked_list_cycle
Open

141. Linked List Cycle#12
ryosuketc wants to merge 2 commits intomainfrom
141_linked_list_cycle

Conversation

@ryosuketc
Copy link
Owner

* https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.rxnrgw1lj851
* どっちでもいいのではという風潮
* https://cpprefjp.github.io/reference/set/set.html
* `contains` C++20 からなので割と新しい。なんでこれがなかったんだろう。まあ `count` とかすればいいのはそうだけど。
Copy link

Choose a reason for hiding this comment

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

Copy link
Owner Author

Choose a reason for hiding this comment

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

(basic_)string にだけ length があるのは、contains などと同じ背景なのかな、と想像しました(一般的なコンテナは size を持つ)。

https://cpprefjp.github.io/reference/vector/vector.html
https://cpprefjp.github.io/reference/string/basic_string.html

* たぶん C++ `==` は値の比較。オブジェクトの比較はポインタを使う (ポインタの `==` はメモリアドレスの比較)
* より厳密には `operator==` の実装依存、という話で、型によって違うという話だと思うが、個別の型でどう実装されているかまではチェックしていない
* https://en.cppreference.com/w/cpp/language/operators.html
* Java のジェネリクスみたいな話なんだと思っているが、ジェネリクス使った実装はやったことがない
Copy link

Choose a reason for hiding this comment

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

Template はコンパイル時にソースコードを自動生成する技術で、Generics は型をつけておいて実行時に解決するものです。Java の Generics はキャストしているだけですね。

上の operator== は演算子のオーバーロードの話なのでまた別です。

Copy link
Owner Author

Choose a reason for hiding this comment

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

なるほど…これが根本的に違うものだというのは理解していませんでした。Template 、なんかマクロのような感じを受けますね (T をコンパイラが実際の type に入れ替えてクラスを生成している)。Template を勉強するときに改めて確認してみます。

Copy link
Owner Author

Choose a reason for hiding this comment

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

しっかり内容を検証してはいないですが、軽く Gemini に聞いてみた内容を記録しておきます。


1. Template はコンパイル時にソースコードを自動生成する技術

これは C++ の Template の特徴を正確に捉えています。

  • 仕組み: C++ の template <typename T> は、それ自体が直接コンパイルされる「コード」ではなく、「コードを生成するための設計図」です。
  • 動作タイミング: コンパイラが、そのテンプレートが実際に使われた箇所(例: std::vector<int>MyFunction<double>())を見つけると、その型(この場合は intdouble)を設計図に当てはめて、その型専用の具体的なコードをコンパイル時に自動生成します。このプロセスを「インスタンス化(実体化)」と呼びます。
  • 結果: std::vector<int> 用のクラスコードと std::vector<string> 用のクラスコードは、コンパイル後のバイナリ内では全く別々のコードとして存在します。
  • 利点: 型ごとに最適化されたコードが生成されるため、実行時のパフォーマンスが非常に高いです(実行時に「何の型だっけ?」と調べるコストや、型変換のコストがかからない)。
  • 欠点: 使われる型ごとにコードが生成されるため、コンパイル時間が長くなったり、最終的な実行ファイルのサイズが大きくなったりする(コード肥大化)可能性があります。

2. Java の Generics はキャストしているだけですね

これも、Java の Generics の実装方法(型消去)を指した、やや簡略化した表現ですが、本質を突いています。

  • 仕組み(型消去 - Type Erasure): Java の ArrayList<String> といったジェネリクスは、コンパイル時の型チェックのためだけに使われます。
  • 動作タイミング: ソースコード上では ArrayList<String>Integer を入れようとするとコンパイルエラーになりますが、コンパイルされてバイトコード(Javaの実行ファイルのようなもの)になる段階で、<String> のような型情報はすべて消去されます。
  • 結果: バイトコード上では、ジェネリクス導入前の古いコードと同じように、すべて Object 型として扱われます。そして、リストから値を取り出す list.get(i) のような箇所で、コンパイラが自動的に (String) という型キャストのコードを裏で挿入します。
  • 「キャストしてるだけ」の意味: このように、Java のジェネリクスは「コンパイル時に安全性をチェックし、実行時は(裏で)キャストに頼る仕組み」であるため、このように表現されることがあります。
  • 利点: 古い Java(ジェネリクスがなかった時代)のコードとの互換性を保ちやすいです。
  • 欠点: 実行時には型情報が失われているため、一部の操作(リフレクションなど)に制約があります。また、実行時にキャストのコストが(わずかですが)発生します。

3. Generics は型をつけておいて実行時に解決するものです

これは "Generics" という言葉を一般論として語っていますが、恐らくコメンテーターは C# の Generics のような実装を念頭に置いている可能性が高いです。

C++ (コンパイル時生成) と Java (型消去) の中間的な実装として、C# や .NET のジェネリクスがあります。

  • 仕組み: C# のジェネリクスは、Java と違って型情報を消去しません。コンパイル後の中間コード(バイトコードに似たもの)にも、実行時にも型情報が保持されます。
  • 動作タイミング: プログラムの実行時(正確には JIT コンパイル時)に、CLR(.NET の実行環境)が必要に応じて型固有のコードを生成します。
  • 結果: C++ のように型固有の最適化されたコード(特に数値などの値型の場合)の恩恵を受けつつ、Java のように実行時まで型情報を保持する柔軟性も持ちます。

まとめ

このコメントは、以下の 3 者の実装方法の違いを対比しています。

  1. C++ Template: コンパイル時に型ごとの実コードを生成(静的・高速)。
  2. Java Generics: コンパイル時に型チェックし、バイトコードでは型情報を消去(実行時は実質キャスト)。
  3. (おそらく) C# Generics: 実行時まで型情報を保持し、実行時に型を解決・コード生成。

コードレビューの文脈では、「C++ の Template は Java のような実行時のキャスト処理(オーバーヘッド)を伴うものではなく、コンパイル時に解決される全く別物(より高速な仕組み)ですよ」という意図で発言されたものと推測されます。

Copy link

Choose a reason for hiding this comment

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

正しいことを言ってそうです。

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.

2 participants