C++ 模板专用化将不同的函数与命名空间操作匹配



我遇到了这样的情况。我在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;
}

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

编译器

没有找到与参数匹配的最专业的模板函数吗?

函数模板不能部分专用化。最后一个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。对于 ADL 不会生效::test_2(_t{});只能找到第一个test_2(及其专用化)。