Also, um Klarheit zu schaffen, gehe ich richtig davon aus, dass die Wurzel des Problems darin liegt, dass der Compiler ohne eine Art Hinweis nicht weiß, dass "apple" ein std::string ist?

Wie in den spitzen Klammern in deinem ersten Beispiel oder dass der zweite Eingabeparameter den gleichen Typnamen wie der Map-Wert in deinem zweiten Beispiel haben wird?
Ich versuche, die automatische Vorlagenargumentdeduktion in C++ zum Laufen zu bringen. Ich habe eine Funktion geschrieben, die eine std::map mit beliebigen zwei willkürlichen Typen als Eingabe akzeptiert und eine Variable mit dem ersten Typ als Ausgabe zurückgibt. Das folgende Beispiel funktioniert und kompiliert erfolgreich:
```
std::map<std::string, int> map1;
map1["apple"] = 1;
string key1 = getkey(map1, 1);
```
Das folgende Beispiel funktioniert nicht:
```
std::map<int, std::string> map2;
map2[1] = "apple";
int key2 = getkey(map2, "apple");
```
Der Compiler sagt, er könne die von der Map verwendeten Typen nicht deduzieren. Was ist die Ursache dafür? Die Ursache dafür ist, dass die Vorlagenargumentdeduktion für Funktionen nicht funktioniert, wenn die Argumente in unterschiedlichen Positionen in der Parameterliste für die beiden Funktionsaufrufe stehen. Im ersten Beispiel ist der Schlüsseltyp std::string und der Werttyp int, sodass die Vorlagenargumentdeduktion korrekt bestimmen kann, dass T std::string und U int ist. Im zweiten Beispiel ist der Schlüsseltyp int und der Werttyp std::string, sodass die Deduktion fehlschlägt, weil die Typen in einer anderen Reihenfolge stehen.

Um dies zu beheben, kannst du die Vorlagenargumente für den Funktionsaufruf explizit angeben:

```c++
int key2 = getkey<int, std::string>(map2, "apple");
```

Alternativ kannst du die Reihenfolge der Vorlagenparameter in der Funktionsdefinition so ändern, dass sie der Reihenfolge der Typen in der Map entspricht:

```c++
template<typename T, typename U>
T getkey(const std::map<T, U>& m, const U& value) {
// ...
}
```

Mit dieser Definition funktionieren beide Funktionsaufrufe ohne explizite Angabe der Vorlagenargumente.
Ja, das ist korrekt. Die Vorlagenargumentdeduktion beruht darauf, dass der Compiler die Typen der Funktionsargumente anhand der Typen der tatsächlichen übergebenen Argumente ableiten kann. Im zweiten von dir bereitgestellten Beispiel kann der Compiler die korrekten Typen nicht deduzieren, weil die Vorlagenparameter-Typen in der Funktionsdefinition in einer anderen Reihenfolge stehen als die tatsächlich übergebenen Argumente. Durch explizite Angabe der Vorlagenargumente oder Umstellen der Vorlagenparameter gibst du dem Compiler einen Hinweis, welche Typen verwendet werden sollen, sodass die Vorlagenargumentdeduktion erfolgreich ist.