C++ 函数模板专业化是如何工作的?

How does C++ function template specialization work?

我正在阅读C++ Primer (5th Edition), 16.5, 定义函数模板特化,对作者给出的示例感到困惑,让我们看一下以下模板函数:

template <typename T> int compare(const T&, const T&);

及其专业化版本:

template <>
int compare(const char* const &p1, const char* const &p2)
{
    return strcmp(p1, p2);
}

T 的类型将是 const char *,但我不认为该函数可以是模板函数的特化版本,因为我认为 const char* const &p1 只能是T const &const T & 的专业化,我知道我错了,但我想知道为什么我错了。

编辑:

有一点要强调,如果我调用compare("hi", "mom"),它不会编译,也就是说template <typename T> int compare(const T&, const T&)不能初始化为int compare(const char* const &p1, const char* const &p2),我知道T 将使用 char[3]char[4] 进行初始化,但既然无法编译,为什么编译器不会忽略这种初始化,而是选择一个可以编译的初始化?

在C++中,const TT const的意思完全一样。因此 const T &T const & 的意思完全一样。

它真的不可能是任何其他方式,因为引用永远无法更改为引用其他内容(它们不是 "reseatable")。如果您将 T const & 读作 "a reference which cannot be changed to refer to a different T",那是不正确的。这是"a reference to a T, which cannot be used to modify that T (and as with all references, cannot be changed to refer to a different T)."

const 可以在类型之前或之后,但指针类型除外,它必须在右侧。

现在棘手的部分是,您示例中的 T 设置为 const char*,这是一个指针类型(指向 const char).该模板表示 T 必须是 const,并且由于它是指针类型,因此必须将特化中的 const 放在类型之后,因此您得到 const char* const

从右向左朗读会更清楚一点:

"a const pointer to a char that is const"

//编辑:

为什么不能打电话给compare("hi", "mom");?因为编译器将这些 char 数组视为不同类型(char[3]char[4]),但模板将两个参数指定为相同类型。

这将匹配模板,但它不会匹配您的专业化(因为 T 现在是 char[2]):

compare("a", "b");

这有效并使用了您的专用方法:

const char * hi = "hi";
const char * mom = "mom";
compare(hi, mom);

//编辑2:

"I know T will be initialized with char[3] or char[4], [...] why won't compiler ignore this kind of initialization but choose one that will compile?"

因为C++是强类型语言。编译器不会为你做猜测工作,它只接受表面值的类型。如果它们不匹配,则它们不匹配。作为开发人员,您的工作就是正确地做到这一点。