human
C ++で動作する自動テンプレート引数控除を取得しようとしています。2つの任意の型を入力としてSTD :: MAPを受け入れる関数を書き、最初のタイプの変数を出力として返します。次の例は、うまく機能し、コンパイルされています。
`` `
std :: map <std :: string、int> map1;
map1 ["apple"] = 1;
文字列key1 = getKey（Map1、1）;
`` `
以下は次のとおりです。
`` `
std :: map <int、std :: string> map2;
Map2 [1] = "Apple";
int key2 = getKey（map2、 "apple"）;
`` `
コンパイラは、マップで使用されるタイプを推測できないと言います。この原因は何ですか？
gpt
この原因は、2つの関数呼び出しのパラメーターリストの異なる位置に引数がある場合、関数のテンプレート引数控除が機能しないことです。最初の例では、キータイプはstd :: stringで、値タイプはintであるため、テンプレート引数控除はtがstd :: stringであり、uはintであることを正しく決定できます。2番目の例では、キータイプはintであり、値タイプはstd :: stringです。したがって、タイプが別の順序であるため、控除は失敗します。

これを修正するには、関数呼び出しのテンプレート引数を明示的に指定できます。

`` c ++
int key2 = getKey <int、std :: string>（map2、 "apple"）;
`` `

または、関数定義のテンプレートパラメーターの順序を再配置して、マップ内のタイプの順序に一致させることができます。

`` c ++
テンプレート<Typename T、TypeName U>
t getKey（const std :: map <t、u>＆m、const u＆value）{
// ...
}
`` `

この定義により、両方の関数への呼び出しは、明示的なテンプレート引数仕様なしで機能します。
human
したがって、明確にするために、問題の根本は、「Apple」が何らかのヒントを提供されることなくSTD ::文字列であることをコンパイラが知らないことを想定するのが正しいですか？

最初の例の角度ブラケットのように、または2番目の入力パラメーターが2番目の例のマップ値と同じタイプネームを持っているように？
gpt
はい、C ++で「Apple」を書くだけで文字列が文字通りになります。

最初の例では、コンパイラはこの引数をSTD :: Stringに変換することを知っています。これは、MAP1が期待するタイプだからです。一方、2番目の例では、テンプレートのGetKey関数は2つのタイプを受信します。Map2のタイプからSTD :: STRINGと、指定したパラメーターから文字通りの文字列を受信し、何らかのヒントなしでそれらを変換する方法を知ることができません。