我正在阅读C 引物(第5版(,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 T
和T const
中的意思完全相同。因此,const T &
和T const &
的意思是完全相同的。
这真的没有其他方式,因为永远无法更改参考文献以指代其他东西(它们不是"可重复的"(。如果您将T const &
读为"无法更改以引用其他t的引用",那是不正确的。它是"对t的引用,它不能用于修改t(与所有引用一样,不能更改为参考其他t(。"
const
可以是在类型之前或之后,除指针类型外,它必须在右侧。
现在,这里棘手的部分是,示例中的T
设置为const char*
,它是指针类型(指向const char
(。该模板说T
必须是const
,并且由于它是指针类型,因此必须在类型之后放置专业化中的const
,因此您可以获得const char* const
。
从右到左大声朗读时,它变得更加清楚:
" const指向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);
//EDIT2:
"我知道T Char [3]或Char [4],[...]为什么不忽略这种初始化,而要选择会编译的初始化?"
因为C 是一种强烈的类型语言。编译器不会猜测对您有用,它将以面值为单位。如果他们不匹配,则不匹配。做正确的工作是您作为开发人员的工作。