<commit_before>======================================================================
Modern C++ Design 読書ノート
======================================================================

テンプレートの専門的な利用技法とデザインパターンを同時に習得できるかもしれない一冊。
読み切るだけでも相当な根気が要る。これを理解するとなると……。

:著者: <NAME>
:訳者: 村上雅章
:出版社: ピアソン・エデュケーション
:ISBN: 4-89471-435-3

.. contents:: ノート目次

ローマ数字ページ各種
======================================================================
* 本書推薦その 1 は <NAME> が寄せている。
  言うまでもなく Effective C++ シリーズの著者だ。

  * <パターン自身をコード化するのではなく、パターンの実装を自動的に生成させる> (p. x)

* 推薦その 2 は <NAME> が寄せている。GoF の一人。

  * <テンプレート・パラメータによって、実行時のオーバーヘッドをまったく発生させずに、
    実装上のトレード・オフを変えることもできるのです> (p. xiii)

* 著者によるまえがきで、本書の目的を明瞭に示している。

  * 対象読者タイプ 1: <C++ プログラマ経験者で最新のライブラリ作成テクニックをマスターしたいと考えている方々>
  * 対象読者タイプ 2: <忙しいプログラマで手っ取り早く作業を済ませてしまう必要がある方々> (p. xviii)
  * <Loki という実在する C++ ライブラリ> (p. xviii) を解説する本である。
  * 本書中のコード例では、Herb Sutter 式コーディング規則を採用。
    もしかして Exceptional C++ Style が関係ある？

* 訳者まえがき

  * <ある種の意思決定は実装段階でなければ行えない> (p. xxiii)
  * <センス・オブ・ワンダーの渦巻く C++ の新世界をお楽しみ下さい>

第 1 章 ポリシーを基にしたクラス・デザイン
======================================================================
* ポリシーとポリシー・クラスとは、重要なクラス設計技術のひとつらしい。
* **ポリシー** とは、<特定の動作や構造上の側面を専門的に受け持った小さなクラス群> (p. 3) のこと。

----

* <プログラミングの天才が若年層に分布しているのに対して、
  ソフトウェア設計の天才がより高年齢層に分布する傾向にある> (p. 4)

* <システム・アーキテクチャには、「設計によってある種の公理を強制する」という
  重要な目標があります> (p. 4)

* <理想的には、設計によって課された制約のほとんどが、コンパイル時点で強制されるべきなのです> (p. 4)

* <組み合わせ爆発と真っ向勝負を挑んではいけない> (p. 5)

* <設計指向のライブラリ> (p. 5)

----

* <いくつかの吟味された基底クラスを用意しておき、
  多重継承によって設計の選択における組み合わせの爆発を取り扱うというアイディアが考えられます。
  （略）しかし、少しでもクラス設計の経験があれば、
  こういった単純な設計がうまく機能しないことは理解できるでしょう> (p. 6)

* <クラス・テンプレートは、通常のクラスではサポートされていないような方法でカスタマイズすることが可能です。
  もし特殊なケースを実装したいのであれば、特定のクラス・テンプレートを生成する際に、
  そのテンプレートにおける任意のメンバ関数を特殊化することができるのです。
  例えば、 ``SmartPtr<T>`` というテンプレートがある場合、
  ``Smart<Widget>`` における任意のメンバ関数を特殊化することができるわけです> (p. 6)

* <さらに、多重パラメータのクラス・テンプレートを用いた場合、
  部分的にテンプレートの特殊化を行うこともできます> (p. 6)

.. code-block:: c++

   // こういう定義がある場合、
   template <class T, class U> class SmartPtr { ... };
   
   // この定義は部分特殊化となる。
   template <class U> class SmartPtr<Widget, U>{ ... };

* <多重継承とテンプレートには相補的なトレード・オフが存在しています> (p. 7)

----

* ポリシーは traits と通じるものがあるが、型ではなく動作を強調する点が異なる。
* ポリシーは「コンパイル時 Strategy パターン」と見ることもできる。
* <ポリシーは、シグネチャ指向ではなく、シンタックス指向なのです> (p. 8)
  <例えば、 ``Creator`` ポリシーでは ``Create`` が static であるか virtual であるかを規定しません> (p. 8)

* **ホスト** または **ホスト・クラス** とは、1 つ以上のポリシーを利用するクラスのことを指す。

----

テンプレート・パラメータに ``template`` を用いる技法が紹介されている。
自分ではこういうクラスを定義することはないが、利用する可能性があるので覚えておくこと。

* ポリシーを使用することで得られる柔軟性

  * 実体化する際のテンプレート引数を変更するだけで、簡単に外部からポリシーを変更できる。
  * アプリケーションに特化した自作ポリシーを提供できる。

----

ポリシー・クラスのデストラクタについて言及あり。

* ポリシーに対してデストラクタを virtual にすると、ポリシーの性質が静的ではなくなる。
  効率のよい解決策としては、デストラクタを非 virtual かつ protected とする。

----

「不完全実体化」の技法について解説あり。

「あるクラス・テンプレートのメンバ関数が使用されない場合、
それは実体化されることがない」すなわちコンパイルエラーが起こらない。

----

* <ポリシーに基づいたクラス設計を行う上で最も難しいのは、
  クラスの機能を正しくポリシーへと分解することです> (p. 20)

* <極端に言えば、ホスト・クラスから固有のポリシーを完全に無くしてしまうのです> (p. 20)

* <過度に一般化されたホスト・クラスの欠点は、
  テンプレート・パラメータが氾濫するということです> (p. 20)

* ``typedef`` の使用によって、秩序だった使用と容易な保守性が保証される。

* <クラスをポリシーに分解する際、
  **直交性のある** (orthogonal) 切り口を見つけ出すことが大変重要になります> (p. 21)
  
  <お互いが完全に独立した> (p. 21) 役割になるように、
  ポリシー分割するのがよいということだな。
  あるポリシーが別のポリシーに干渉するようではまずい。

第 2 章 テクニック
======================================================================<commit_msg>* source/alexandrescu01.rst: 第 2 章をノート。<commit_after>======================================================================
Modern C++ Design 読書ノート
======================================================================

テンプレートの専門的な利用技法とデザインパターンを同時に習得できるかもしれない一冊。
読み切るだけでも相当な根気が要る。これを理解するとなると……。

:著者: <NAME>
:訳者: 村上雅章
:出版社: ピアソン・エデュケーション
:ISBN: 4-89471-435-3

.. contents:: ノート目次

ローマ数字ページ各種
======================================================================
* 本書推薦その 1 は <NAME> が寄せている。
  言うまでもなく Effective C++ シリーズの著者だ。

  * <パターン自身をコード化するのではなく、パターンの実装を自動的に生成させる> (p. x)

* 推薦その 2 は <NAME> が寄せている。GoF の一人。

  * <テンプレート・パラメータによって、実行時のオーバーヘッドをまったく発生させずに、
    実装上のトレード・オフを変えることもできるのです> (p. xiii)

* 著者によるまえがきで、本書の目的を明瞭に示している。

  * 対象読者タイプ 1: <C++ プログラマ経験者で最新のライブラリ作成テクニックをマスターしたいと考えている方々>
  * 対象読者タイプ 2: <忙しいプログラマで手っ取り早く作業を済ませてしまう必要がある方々> (p. xviii)
  * <Loki という実在する C++ ライブラリ> (p. xviii) を解説する本である。
  * 本書中のコード例では、Herb Sutter 式コーディング規則を採用。
    もしかして Exceptional C++ Style が関係ある？

* 訳者まえがき

  * <ある種の意思決定は実装段階でなければ行えない> (p. xxiii)
  * <センス・オブ・ワンダーの渦巻く C++ の新世界をお楽しみ下さい>

第 1 章 ポリシーを基にしたクラス・デザイン
======================================================================
* ポリシーとポリシー・クラスとは、重要なクラス設計技術のひとつらしい。
* **ポリシー** とは、<特定の動作や構造上の側面を専門的に受け持った小さなクラス群> (p. 3) のこと。

----

* <プログラミングの天才が若年層に分布しているのに対して、
  ソフトウェア設計の天才がより高年齢層に分布する傾向にある> (p. 4)

* <システム・アーキテクチャには、「設計によってある種の公理を強制する」という
  重要な目標があります> (p. 4)

* <理想的には、設計によって課された制約のほとんどが、コンパイル時点で強制されるべきなのです> (p. 4)

* <組み合わせ爆発と真っ向勝負を挑んではいけない> (p. 5)

* <設計指向のライブラリ> (p. 5)

----

* <いくつかの吟味された基底クラスを用意しておき、
  多重継承によって設計の選択における組み合わせの爆発を取り扱うというアイディアが考えられます。
  （略）しかし、少しでもクラス設計の経験があれば、
  こういった単純な設計がうまく機能しないことは理解できるでしょう> (p. 6)

* <クラス・テンプレートは、通常のクラスではサポートされていないような方法でカスタマイズすることが可能です。
  もし特殊なケースを実装したいのであれば、特定のクラス・テンプレートを生成する際に、
  そのテンプレートにおける任意のメンバ関数を特殊化することができるのです。
  例えば、 ``SmartPtr<T>`` というテンプレートがある場合、
  ``Smart<Widget>`` における任意のメンバ関数を特殊化することができるわけです> (p. 6)

* <さらに、多重パラメータのクラス・テンプレートを用いた場合、
  部分的にテンプレートの特殊化を行うこともできます> (p. 6)

.. code-block:: c++

   // こういう定義がある場合、
   template <class T, class U> class SmartPtr { ... };
   
   // この定義は部分特殊化となる。
   template <class U> class SmartPtr<Widget, U>{ ... };

* <多重継承とテンプレートには相補的なトレード・オフが存在しています> (p. 7)

----

* ポリシーは traits と通じるものがあるが、型ではなく動作を強調する点が異なる。
* ポリシーは「コンパイル時 Strategy パターン」と見ることもできる。
* <ポリシーは、シグネチャ指向ではなく、シンタックス指向なのです> (p. 8)
  <例えば、 ``Creator`` ポリシーでは ``Create`` が static であるか virtual であるかを規定しません> (p. 8)

* **ホスト** または **ホスト・クラス** とは、1 つ以上のポリシーを利用するクラスのことを指す。

----

テンプレート・パラメータに ``template`` を用いる技法が紹介されている。
自分ではこういうクラスを定義することはないが、利用する可能性があるので覚えておくこと。

* ポリシーを使用することで得られる柔軟性

  * 実体化する際のテンプレート引数を変更するだけで、簡単に外部からポリシーを変更できる。
  * アプリケーションに特化した自作ポリシーを提供できる。

----

ポリシー・クラスのデストラクタについて言及あり。

* ポリシーに対してデストラクタを virtual にすると、ポリシーの性質が静的ではなくなる。
  効率のよい解決策としては、デストラクタを非 virtual かつ protected とする。

----

「不完全実体化」の技法について解説あり。

「あるクラス・テンプレートのメンバ関数が使用されない場合、
それは実体化されることがない」すなわちコンパイルエラーが起こらない。

----

* <ポリシーに基づいたクラス設計を行う上で最も難しいのは、
  クラスの機能を正しくポリシーへと分解することです> (p. 20)

* <極端に言えば、ホスト・クラスから固有のポリシーを完全に無くしてしまうのです> (p. 20)

* <過度に一般化されたホスト・クラスの欠点は、
  テンプレート・パラメータが氾濫するということです> (p. 20)

* ``typedef`` の使用によって、秩序だった使用と容易な保守性が保証される。

* <クラスをポリシーに分解する際、
  **直交性のある** (orthogonal) 切り口を見つけ出すことが大変重要になります> (p. 21)
  
  <お互いが完全に独立した> (p. 21) 役割になるように、
  ポリシー分割するのがよいということだな。
  あるポリシーが別のポリシーに干渉するようではまずい。

第 2 章 テクニック
======================================================================
* 静的チェックの必要性。すなわち、コンパイル時版 ``assert`` だ。
  <評価される式がコンパイル時の定数になるのであれば、
  実行時ではなく、コンパイル時にチェックを行うことができるはずです> (p. 26)

.. code-block:: c++

   template<bool> struct CompileTimeError;
   template<> struct CompileTimeError<true>{};
   
   #define STATIC_CHECK(expr) \
      (CompileTimeError<(expr) != 0>())

* 上記のマクロからスタートし、エラーメッセージをなるべく読み易くするように工夫を重ねていく。
* 省略記号 ``(...)`` を用いた関数宣言を利用する。

----

.. code-block:: c++

   template <class Window, class Controller>
   class Widget
   {
      ...
   };
   
   // テンプレート全体を明示的に特殊化する場合の例。
   template <>
   class Widget<ModalDialog, MyController>
   {
      ...
   };
   
   // 任意の Window や MyController に対して特殊化する場合（部分特殊化）。
   template <class Window>
   class Widget<Window, MyController>
   {
      ...
   };

* <クラス・テンプレートの部分的な特殊化では、テンプレート引数の一部だけを記述し、
  その他の引数を元のままにしておく> (p. 29)

* <テンプレートの部分的な特殊化は、メンバ関数、非メンバ関数を問わず、
  関数には適用されません> (p. 30) が、こういう場合は関数のオーバーロードを併用する。

----

* ローカルクラスの話題だが、他のプログラミング言語を知っている人間なら驚かないかも。
* ローカルクラスの特徴

  * ローカルクラスでは static メンバを定義できない。
  * ローカルクラスから（それを含む関数定義内にある）非 static のローカル変数にアクセスできない。
  * 関数テンプレート内でローカルクラスを定義することができ、
    それを囲んでいる関数のテンプレート・パラメータを用いることもできる。

----

.. code-block:: c++

   template <int v>
   struct Int2Type
   {
     enum { value = v };
   };

* 例えば <``Int2Type<0>`` と ``Int2Type<1>`` は異なった型> (p. 31) となる。
  このようなクラスの応用例として、p. 33 の ``NiftyContainer::DoSomething`` を覚えておくこと。

----

.. code-block:: c++

   template <typename T>
   struct Type2Type
   {
     typedef T OriginalType;
   };

* ``Type2Type`` もオーバーロード関数の仮引数の型としてだけ利用する。
  p. 35 の関数テンプレート ``Create`` のオーバーロードに注目。

----

* <ブーリアン定数によって様々な型から特定の型を選択しなければならない場合> (p. 35)

.. code-block:: c++

   template <bool flag, typename T, typename U>
   struct Select
   {
     typedef T Result;
   };
   
   template <typename T, typename U>
   struct Select<false, T, U>
   {
     typedef U Result;
   };

.. code-block:: c++

   template <typename T, bool isPolymorphic>
   class NiftyContainer
   {
     // ここでコンテナの収容型を typedef するのに
     // Select を利用できる。
   };

----

* <何も情報が与えられていない 2 つの型 ``T`` と ``U`` がある場合、
  ``U`` が ``T`` を継承しているかどうか、そのようにすれば判るのでしょうか> (p. 37)
* <任意の型 ``T`` が任意の型 ``U`` への自動変換をサポートしているかどうかは、
  どのように検出すればよいのでしょうか> (p. 37)

* 脚注にいいことが書いてある。
  <``sizeof`` はいずれにしても型を検出しなければならないため、
  ``typeof`` と ``sizeof`` は明らかに同じバックエンドを共有しているのです> (p. 37)

* 解決策は、まず p.38 のアイディアをコードに落として、
  それから p. 39 のクラステンプレート ``Conversion`` の中にすべて閉じ込めるというもの。
  省略記号をとる関数オーバーロード、
  定義なし関数宣言と ``sizeof`` のペアをうまく組み合わせている。

----

* <``typeid`` 演算子とは、 ``type_info`` オブジェクトへの参照を返すものです> (p. 40)
  個人的にはこれまでの C++ 経験で ``typeid`` を利用した記憶がない。

* ``type_info`` の特徴 (p. 41)

  * ``name`` というメンバ関数があるが、クラス名を文字列に対応づける方法は標準化されていない。
  * ``before`` メンバ関数が ``type_info`` 型の順序関係を定義する。
  * コピーコンストラクタと代入演算子が無効化されている。
    何が言いたいかというと、「値」を何か変数に格納できないということ。
  * ``typeid`` が返すオブジェクトは静的記憶域内に存在する。

* つかいにくいので、ラッパークラスを定義する。

----

.. code-block:: c++

   class NullType{};
   struct EmptyType{}; // 継承を許す。

----

* <特性 (traits) とは、値に基づく決定が実行時に行えるのと同様に、
  型に基づく決定をコンパイル時に行えるようにするジェネリックなプログラミング・テクニックです
  (Alexandrescu 2000a)> (p. 43)

* ``std::copy`` の実装にこの技法が採用されていることが多いようだ。

* <ある型 ``T`` のオブジェクトを引数として関数間で授受する場合、（略）
  一般的に最も効率の良い方法とは、複雑な型を参照で、
  スカラ型は値で引き渡すことです> (p. 46)

* <ここで注意が必要なのは、C++ では参照への参照が許されないという点です> (p. 47)

  ``std::bind2nd`` と ``std::mem_fun`` を組み合わせた場合に、
  このエラーが発生することも言及している。

* <型が ``enum`` かどうかを判断する方法は存在しない> (p. 47)
* ``enum`` と言えば、p. 49 のコードを見て知ったが、
  関数定義の中で ``enum`` を定義できるようだ。

第 3 章 タイプリスト
======================================================================
{'fraction_non_alphanumeric': 0.20491482279224593, 'fraction_numerical': 0.013119248090855688, 'mean_word_length': 5.0912343470483, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3796674', 'n_tokens_mistral': 7827, 'n_tokens_neox': 7228, 'n_words': 695}