I'm trying to figure out how implicit instantiation of function arguments works. For some reason in the first example, the bar() call interprets the {12,41} as an initializer list. If I change the foo signature to auto foo(std::pair<int,int> bar) the {12,41} is implicitly converted to an std::pair<int,int>.
For example
template<typename T, typename U>
auto foo(std::pair<T,U> arg) { return arg; }
auto bar() { return foo({12,41}); }
fails with error:
<source>: In function 'auto bar()':
104 : <source>:104:50: error: no matching function for call to 'foo(<brace-enclosed initializer list>)'
auto bar() { return foo({12,41}); }
^
103 : <source>:103:6: note: candidate: 'template<class T, class U> auto foo(std::pair<_T1, _T2>)'
auto foo(std::pair<T,U> arg) { return arg; }
^~~
103 : <source>:103:6: note: template argument deduction/substitution failed:
104 : <source>:104:50: note: couldn't deduce template parameter 'T'
auto bar() { return foo({12,41}); }
^
but
auto foo(std::pair<int,int> arg) { return arg; }
auto bar() { return foo({12,41}); }
works. Would someone care to elaborate why?