我有关于c ++函数匹配优先级的简单问题。假设我有这样的代码:
#include <iostream>
void func(const char*)
{
std::cout << "const char*" << std::endl;
}
template<int N>
void func(const char (&) [N])
{
std::cout << "const char (&) [N]" << std::endl;
}
int main(int argc, char* argv[])
{
func("Hello world");
return 0;
}
代码的结果是(带Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
):
const char*
我认为"Hello world"
的文字类型应为const char[]
。为什么const char*
版本的优先级高于const char (&)[]
版本?
答案 0 :(得分:6)
重载解析尝试找到最佳转换。以下段落列出了可以区分两种转换的相关要点:
标准转换序列
S1
是一个比转换序列更好的转换序列 标准转换序列S2
if
S1
是S2
的正确子序列(比较13.3.3.1.1定义的规范形式的转换序列,排除任何 左值变换;考虑身份转换序列 成为任何非身份转换序列的子序列)或者,如果 不是那样,
S1
的排名优于S2
的排名,或者S1
和S2
具有相同的排名,并且可以通过 以下段落中的规则,或者,如果不是,[...]
虽然函数模板的特化产生了带有标识转换的参数,但是char const*
的非模板重载需要进行数组到指针的转换。直觉上,我们说前者是更好的匹配,因此应该被选中。但是,数组到指针的转换是Lvalue Transformation,从第一个项目符号点中排除。由于它具有完全匹配等级,因此转换的等级与char const (&)[N]
的转换等级不同,后者也具有完全匹配等级。 &#34;以下段落中的规则&#34;也无法区分转换,因为它们只能解决派生到基本的转换等问题,而不是数组到指针。
事实上,转换为char const (&)[N]
并不是更好。但是重载决策会区分模板:
鉴于这些定义,可行函数
F1
被定义为a 如果适用于所有参数,则比另一个可行函数F2
具有更好的功能 i ,ICS i (F1)的转换序列不比ICS i (F2)差,然后
对于某些参数 j ,ICS j (F1)是一个更好的转换 序列比ICS j (F2),或者,如果不是,
[...]
<强>
F1
不是函数模板特化,F2
是函数 模板专业化,或者,如果不是,
因此选择了非模板重载。
答案 1 :(得分:3)
在您的特定情况下,应用的解决规则的相关部分是非模板函数优先于模板函数,这就是您看到指针而不是数组引用的原因。