“专业化不参与超载”

anu*_*g86 4 c++ templates

这是什么真正的意思是“专业化的函数模板不参与重载决议的一部分。只有基本模板被认为是”

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

// 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"
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>
void f(T const&)
{
        std::cout<<std::endl<<"Base Template for f() called\n";
}

template<>
void f<char const * const &>(char const* const&)
{
        std::cout<<std::endl<<"Specialized f() for char const* called\n";
}
f("Hello") //prints "Base Template for f() called"
Run Code Online (Sandbox Code Playgroud)

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

Sne*_*tle 5

如果您尝试max(5, 7.0),即使 adouble可转换为,您也会收到错误消息int。所以特intmax不参与重载决议。

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)
Run Code Online (Sandbox Code Playgroud)

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

template <typename T>
T max(T a, T b);

int max(int a, int b);

max(5, 7.0); // this is fine
Run Code Online (Sandbox Code Playgroud)

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

  • 完全匹配的函数(例如max(int, double)。所以max(int, int)在这个阶段不会被考虑)
  • 匹配函数模板(例如max(T, U)。所以max(T, T)不会被考虑,因为T不能同时是intdouble
  • 具有兼容参数的函数(例如,max(int, int)因为double可以隐式转换为int

请注意,我没有提到函数模板专业化。如果找到匹配的函数模板,则将使用完全匹配的特化(因此,如果您专门用于doubles 但您使用ints调用,则不会使用该特化),否则将使用基本模板。

有关更好的解释,请参阅cppreference

  • 哦,我看到你的困惑。`"hello"` 的类型不是 `const char *`。它是“const char [6]”。这与专业化不完全匹配,因此使用基本模板。 (2认同)