部分模板特化可能不适用于函数,但重载不是同一件事吗?

Partial template specialization may not work for functions, but isn't overloading the same thing?

缺少 "partial template specialization" 功能实际上是一个缺点吗?当我定义一个模板,连同一个重载以充当专业化时,它似乎总是有效。

template<typename T>
static T Func(T a) { std::cout << "a"; return a; }
static long Func(long a) { std::cout << "b"; return a; }

如中,在推理上与Func<long>不冲突。即 Func(22l); 调用正确的函数并且没有歧义。

这不就和函数的模板特化一样好吗?公开此类功能是否存在我需要注意的陷阱?

编辑:我看到一个区别是 Func<long> 不可能调用重载,所以这里需要推理......绝对是一个潜在的混淆来源,特别是如果从另一个模板引用它。

另一个编辑:如前所述,这是一个完整的专业化,而不是部分专业化。幸运的是它似乎仍然适用于 partial:

template<typename T, typename U>
static U Func(T a, U b) { std::cout << "a"; return a; }
template<typename T>
static long Func(T a, long b) { std::cout << "b"; return a; }

Func<long>(12, 22);  // invokes template
Func<long>(12, 22l); // invokes "specialization"

考虑

template<class R, class T>
R convert(const T&);

假设我们想为 convert<void>(/*something*/) 做一些特别的事情(即 Rvoid 的情况)。您不能通过简单的重载或完全专业化来做到这一点。 (通常的技巧是委托给助手 class 模板的静态成员函数,它可以部分特化。)