帮忙判断下这段代码中模板函数的匹配原则应该如何理解?

#include <iostream>
using namespace std;

template <typename T, typename Q, typename H>
void func(T t, Q q, H h)
{
    cout << 1 << endl;
}

template <typename T, typename Q>
void func(T t, T t2, Q q)
{
    cout << 2 << endl;
}

template <>
void func(int a, int b, double c)
{
    cout << 3 << endl;
}

int main()
{
    func(1, 1, 1.0);
}

上面这段输出为3,也就是说匹配到的是第3个具体化的void func(int a, int b, double c)

如果我把后2个具体化的模板函数位置对调一下:

#include <iostream>
using namespace std;

template <typename T, typename Q, typename H>
void func(T t, Q q, H h)
{
    cout << 1 << endl;
}

template <>
void func(int a, int b, double c)
{
    cout << 3 << endl;
}

template <typename T, typename Q>
void func(T t, T t2, Q q)
{
    cout << 2 << endl;
}

int main()
{
    func(1, 1, 1.0);
}

这样输出就变成2了,匹配到的模板函数是void func(T t, T t2, Q q)

没有想明白为什么2个具体化的函数的先后顺序会影响到匹配结果呢?

其实这两个模板与main()中的参数都是匹配的,此时非实例优先。如果要实例化所有参数,尽量不要加上template<>。也就是说,输出3的实例版本函数如下这样写,不管怎么调换定义的先后顺序,程序都会输出3.

void func(int a, int b, double c)
{
cout << 3 << endl;
}