我正在阅读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)
,我知道{{ 1}}将使用T
或char[3]
进行初始化,但是现在这不会编译,为什么不会让编译器忽略这种初始化但是选择一个会编译的?<\ n} / p>
答案 0 :(得分:3)
在C ++中,const T
和T const
的含义完全相同。因此,const T &
和T const &
的含义完全相同。
它实际上不可能是任何其他方式,因为永远不能更改引用以引用其他内容(它们不是“可重定位”)。如果您将T const &
读作“无法更改以引用其他T的引用”,则表示不正确。它是“对T的引用,不能用于修改T(和所有引用一样,不能更改为引用不同的T)。”
答案 1 :(得分:2)
pString->data[count] = getc(fp);
count++; // count is not restricted from growing
可以在类型之前或之后,除了指针类型,它必须位于右侧。
现在这里棘手的部分是,示例中的const
设置为T
,这是指针类型(指向const char*
的指针) 。模板说const char
必须是T
,并且由于它是指针类型,因此专业化中的const
必须放在类型之后,因此得到{{1} }}
从右到左大声朗读它会变得更加清晰:
&#34;一个指向char的常量指针&#34;
<强> //编辑:强>
为什么不打电话给const
?因为编译器(const char* const
和compare("hi", "mom");
)将这些char数组视为不同类型,但模板将两个参数指定为相同的类型。
这将与模板匹配,但它与您的专业化不匹配(因为char[3]
现在是char[4]
):
T
这适用于您的专业方法:
char[2]
<强> // EDIT2:强>
&#34;我知道T将使用char [3]或char [4]初始化,[...]为什么不会让编译器忽略这种初始化但是选择一个会编译的?&#34;
因为C ++是一种强类型语言。编译器不会为你猜测工作,它采用面值的类型。如果他们不匹配,他们就不匹配。作为开发人员,您的工作是正确的。