デフォルトパラメータを持つテンプレートは、C++における汎用プログラミングの強力なメカニズムです。
問題の歴史:
テンプレートはSTLライブラリの始まりでした。後に、テンプレート関数およびクラスのパラメータにデフォルト値を指定する機能が追加され、テンプレートをより汎用的にし、コードの拡張性をサポートすることができました。
問題:
通常の関数とテンプレートのオーバーロードが存在する場合、また特化におけるあいまいさが発生することによる、明白でない衝突があります。テンプレートにおけるデフォルトパラメータは柔軟性を高めることができますが、しばしば難解なコンパイルエラーを引き起こします。
解決策:
特に非テンプレートバージョンと交差する場合、テンプレート内のデフォルト値の数を最小限に抑える方が良いです。関数呼び出しの優先順位は、テンプレート関数ではなく、通常の関数との完全一致を優先します。
コードの例:
template<typename T = int> T multiply(T a, T b = T(2)) { return a * b; } int multiply(int a, int b) { return a + b; }
呼び出し multiply(5, 4) は int multiply(int, int) 関数を選択し、呼び出し multiply<>(5) はテンプレートを呼び出し、bは2の値を取ります。
主な特徴:
テンプレート関数の次の定義でデフォルトパラメータを宣言できますか?
いいえ、デフォルト値は1つの場所(通常は宣言)にのみ指定でき、それ以外の場所で指定するとコンパイルエラーになります。
テンプレートと非テンプレート関数間のあいまいさがある場合、何が起こりますか?コンパイラーは何を呼び出すかをどのように決定しますか?
コンパイラーは、引数に正確に適合する非テンプレート関数を常に優先します。テンプレートは、正確な一致がない場合にのみ呼び出されます。
テンプレートのパラメータ(例えば、数)に対してデフォルト値を指定できますか?
はい、例えば:
template<typename T, int N = 8> class Array { T data[N]; };
ネガティブケース
テンプレート関数と非テンプレート関数が同じパラメータとデフォルト値で宣言され、あるモジュールでは呼び出しが意図した通りに動作し、別のモジュールでは意図しない関数バージョンが選択される。
プラス:
マイナス:
ポジティブケース
交差する構成のためにテンプレート関数と非テンプレート関数に明示的に異なる命名があり、デフォルト値は1つのバージョンのみにあります。
プラス:
マイナス: