#include <iostream>
struct A {
A() : m_parts(3) {};
int m_parts;
};
struct B {
B() : m_parts(4) {};
int m_parts;
};
template <typename T, typename U>
int foo(const T& t, const U& u)
{
std::cout << "In foo(T, U)" << std::endl;
return t.m_parts + u.m_parts;
}
template <typename T>
int foo(const T& t1, const T& t2)
{
std::cout << "In foo(T, T)" << std::endl;
return t1.m_parts + t2.m_parts;
}
int main()
{
A a;
B b;
auto v1 = foo(a, b); std::cout << v1 << std::endl;
auto v2 = foo(a, a); std::cout << v2 << std::endl;
auto v3 = foo(b, b); std::cout << v3 << std::endl;
}
I was half surprised by this, and half expected it.
If I were to get rid of the second template
1 2
template <typename T>
int foo(const T& t1, const T& t2)
,
the code still compiles fine using only the <T, U> template.
So why isn't it ambiguous to have both function templates here? Why does the compiler choose the <T> template even though it sees the valid <T, U> template first?
Overload resolution does not simply accept first candidate, so both have to be considered. Partial ordering of overloaded function templates makes the decision.