我有关于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;
}
Run Code Online (Sandbox Code Playgroud)
代码的结果是(with Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
):
const char*
Run Code Online (Sandbox Code Playgroud)
我认为"Hello world"
应该是文字类型const char[]
.为什么const char*
版本的优先级高于const char (&)[]
版本?
重载决策尝试找到最佳转换.以下段落列出了可以区分两种转换的相关要点:
标准转换序列
S1
比标准转换序列更好的转换序列S2
,如果
S1
是一个适当的子S2
序列(比较13.3.3.1.1定义的规范形式的转换序列,不包括任何左值变换 ;身份转换序列被认为是任何非同一性转换序列的子序列),或者,如果不是,军衔
S1
比的排名更好S2
,或S1
与S2
具有相同的等级,并在下面的段落中的规则区分,或者,如果不说,[...]
虽然函数模板的特化产生带有标识转换的参数,但非模板重载char const*
需要进行数组到指针的转换.直觉上,我们说前者是更好的匹配,因此应该被选中.但是,数组到指针的转换是Lvalue Transformation,从第一个项目符号点中排除.并且由于它具有完全匹配等级,因此转换的等级与转换的等级没有不同,转换等级char const (&)[N]
也具有完全匹配等级."下面段落中的规则"无法区分转换,因为它们仅针对派生到基本的转换等,而不是数组到指针.
事实上,转换到char const (&)[N]
任何方式都不是更好.但是重载决策会区分模板:
给定这些定义,如果对于所有参数 i,ICS i(F1)不是比ICS i(F2)更差的转换序列,则可行函数
F1
被定义为比另一个可行函数更好的函数,然后F2
对于某些参数j,ICS j(F1)是比ICS j(F2)更好的转换序列,或者,如果不是,
[...]
F1
不是函数模板特化,F2
是一个函数模板特化,或者,如果不是,
因此,选择了非模板重载.