I am trying to get automatic template argument deduction to work in C++. I have written a function which accepts a std::map with any two arbitrary types as its input, and returns a variable with the first type as its output. The following example works and compiles successfully:
```
std::map<std::string, int> map1;
map1[apple] = 1;
string key1 = getkey(map1, 1);
```
The following does not:
```
std::map<int, std::string> map2;
map2[1] = apple;
int key2 = getkey(map2, apple);
```
The compiler says it cannot deduce the types used by the map. What is the cause of this?
The cause of this is that template argument deduction for functions does not work when the arguments are in different positions in the parameter list for the two function calls. In the first example, the key type is std::string and the value type is int, so the template argument deduction can correctly determine that T is std::string and U is int. In the second example, the key type is int and the value type is std::string, so the deduction fails because the types are in a different order.

To fix this, you can explicitly specify the template arguments for the function call:

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

Alternatively, you can rearrange the order of the template parameters in the function definition to match the order of the types in the map:

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

With this definition, both calls to the function will work without explicit template argument specification.
So, for clarity, am I correct to assume that the root of the problem is that the compiler won't know that apple is an std::string without being provided some kind of a hint?

Like in the angle brackets in your first example, or that the second input parameter will have the same typename as the map value in your second example?
Yes, that's correct. Template argument deduction relies on the compiler being able to deduce the types of the function arguments based on the types of the actual arguments passed in. In the second example you provided, the compiler cannot deduce the correct types because the template parameter types in the function definition are in a different order than the actual arguments passed in. By explicitly specifying the template arguments or rearranging the template parameters, you provide a hint to the compiler as to what types to use, allowing template argument deduction to succeed.