C++ 模板特化将不同的函数与命名空间 op 相匹配

C++ Template specialization matches different functions with namespace op

我 运行 遇到了这样的情况。我在 Windows 10.

上使用 g++
#include <stdio.h>

template<typename _t>
struct test_thing {};

template<typename _t> void test_2(_t) { printf("A"); }

template<typename _t>
void test()
{
    //test_2(_t{}); // prints: ABC
    ::test_2(_t{}); // prints: ABA    <-- namespace op, searching different?
}

template<>            void test_2(double)         { printf("B"); }
template<typename _t> void test_2(test_thing<_t>) { printf("C"); }

int main()
{
    test<int>();
    test<double>();
    test<test_thing<int>>();

    return 0;
}

我的问题是 why/how 是命名空间 op 改变了编译器搜索要调用的函数的方式。编译器难道没有找到与参数匹配的最专业的模板函数吗?如果 test_2(test_thing<_t>) 定义在 test 之上,它会找到它,但只能使用 ::,而不是下面。

Doesn't the compiler find the most specialized template function that matches the args?

函数模板不能部分特化。最后一个 test_2 与第一个重载。

template<typename _t> void test_2(_t) { printf("A"); } // overload #1

template<typename _t>
void test()
{
    //test_2(_t{}); // prints: ABC
    ::test_2(_t{}); // prints: ABA    <-- namespace op, searching different?
}

template<>            void test_2(double)         { printf("B"); } // explicit specialization for overload#1
template<typename _t> void test_2(test_thing<_t>) { printf("C"); } // overload #2

给定 test_2(_t{});ADL 帮助并找到第二个重载 test_2。因为::test_2(_t{}); ADL不会生效,只能找到第一个test_2(及其特化)。