"专业化不参与超载"

"specializations don’t participate in overloading"

本文关键字:超载 专业化      更新时间:2023-10-16

"函数模板的专业化"的真正含义是什么 不要参与重载解析。仅考虑基本模板">

我用它的专用版本编写了一个简单的模板函数,可以看到专用函数被称为:

// Base template
template <typename T>
T max(T a, T b) {
std::cout << "Base Template" << std::endl;
return (a>b) ? a : b;
}
// Specialization for int
template<>
int max<int>(int a, int b) {
std::cout << "int specialization" << std::endl;
return (a>b) ? a : b;
}
max(2,3);// prints "int specialization"

查看与此概念相关的其他 StackOverflow,我找到了另一篇文章,以证明专业化不参与重载,他展示了以下示例,其中没有调用专用版本,我仍然不确定为什么没有调用它。但除此之外,在此示例中,参数没有变量名称,仍然没有部分(char const* const&)的编译或运行时错误

template<typename T>
void f(T const&)
{
std::cout<<std::endl<<"Base Template for f() calledn";
}
template<>
void f<char const * const &>(char const* const&)
{
std::cout<<std::endl<<"Specialized f() for char const* calledn";
}
f("Hello") //prints "Base Template for f() called"

总而言之,我仍在试图弄清楚"函数模板的专业化不参与重载解析"的含义。只考虑基本模板",如果有人可以用一个例子来解释(以及为什么在第二个示例中调用基本模板(。 其次,为什么程序编译并运行良好,在第二个示例中没有变量名称。

如果您尝试max(5, 7.0),即使double可转换为int,您也会收到错误。因此,maxint专业化不参与过载解决。

template <typename T>
T max(T a, T b);
template <>
int max(int a, int b);
max(5, 7.0); // compiler error (no matching function)

但是,如果您使用的是常规函数而不是模板专用化,您将获得预期的行为。

template <typename T>
T max(T a, T b);
int max(int a, int b);
max(5, 7.0); // this is fine

当编译器考虑参数类型时(int, double),它会按以下顺序查找函数(使用 ADL 和其他细节比这稍微复杂一些(:

  • 完全匹配的函数(例如max(int, double).所以max(int, int)现阶段不会考虑(
  • 匹配的功能模板(例如max(T, U).所以max(T, T)不会被考虑,因为T不能既intdouble(
  • 具有兼容参数的函数(例如max(int, int)因为double隐式转换为int(

请注意,我没有提到函数模板专用化。如果找到匹配的函数模板,将使用完全匹配的专用化(因此,如果您专门针对double,但您调用int,则不会使用专用化(,否则将使用基本模板。

有关更好的说明,请参阅 cpp首选项。