ProgrammingC++開発者、リード開発者

デフォルトパラメータを持つ関数およびクラスのテンプレートはどのように機能しますか?使用の際の注意点は何ですか?テンプレート関数と非テンプレート関数間で矛盾がある場合はどうすればよいですか?

Hintsage AIアシスタントで面接を突破

回答。

デフォルトパラメータを持つテンプレートは、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つのバージョンのみにあります。

プラス:

  • 明示的な動作。
  • 呼び出しの衝突がない。

マイナス:

  • 関数のバージョンをサポートするために若干多くのコードが必要。