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 T
和T 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++是强类型语言。编译器不会为你做猜测工作,它只接受表面值的类型。如果它们不匹配,则它们不匹配。作为开发人员,您的工作就是正确地做到这一点。
我正在阅读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 T
和T 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++是强类型语言。编译器不会为你做猜测工作,它只接受表面值的类型。如果它们不匹配,则它们不匹配。作为开发人员,您的工作就是正确地做到这一点。