過負荷と特殊化。 微妙な瞬間

今日の短いメモでは、関数のオーバーロードと特殊化に関連する微妙な点について説明します。 少し前に私は実際に会って、このトピックに関する私の個人的なデータベースの記録を更新する理由がありました。 この情報を共有します。





template<typename T> void foo(T); // 1 template<> void foo(int*); // 2 template<typename T> void foo(T*); // 3 template<typename T> void bar(T); // 4 template<typename T> void bar(T*); // 5 template<> void bar(int*); // 6 void f() { int i; foo(&i); bar(&i); }
      
      





したがって、2つの完全に同一の関数セットがありますが、ご存知のように、キャッチなしでは機能しません。 それらのどれが呼び出されますか?



解説



今日3と6に答えた人は、ハブでのんびり過ごす時間よりも30分以上長く過ごすことができます この動作を説明するには、オーバーロードに関して存在する関数のカテゴリを覚えておく必要があります。



1.通常の機能;

2.基本パターン。 これらは次の形式の関数です

 template<typename T> void bar(T);
      
      





3.機能テンプレートの専門化。



これら3つのカテゴリ間のオーバーロード解決に対するコンパイラの動作が期待されます。 最初に、通常の機能と基本テンプレートの中から最適な候補が選択され、通常の機能が優先されます。 基本テンプレートがより適切である場合、さらに適切な特殊化があるかどうかがチェックされ、もしあれば、そのうちの1つが選択されます。



微妙な点は、テンプレート関数の特殊化がそのように考慮されるためには、この特殊化の前にコードで基本テンプレートを宣言する必要があるということです。



つまり、上記の例では、(2)は(3)ではなく(1)特殊化であるため、より適切なベーステンプレート(3)がオーバーロードに選択されます。 2番目のケースでは、(6)は特殊化(5)であり、(4)よりも優れた候補です。



All Articles