Template evaluation with more than one template type

The following code is not ambiguous,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#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.
Thank you, I wasn't sure what to call it, I'll look more into the rules of the overloading to see when it chooses what.
Last edited on
Topic archived. No new replies allowed.