C ++函数匹配优先级

时间:2015-04-30 07:02:33

标签: c++ function

我有关于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 (&)[]版本?

2 个答案:

答案 0 :(得分:6)

重载解析尝试找到最佳转换。以下段落列出了可以区分两种转换的相关要点:

  

标准转换序列S1是一个比转换序列更好的转换序列   标准转换序列S2 if

     
      
  • S1S2的正确子序列(比较13.3.3.1.1定义的规范形式的转换序列,排除任何   左值变换;考虑身份转换序列   成为任何非身份转换序列的子序列)或者,如果   不是那样,

  •   
  • S1的排名优于S2的排名,或者S1S2具有相同的排名,并且可以通过   以下段落中的规则,或者,如果不是,

  •   
  • [...]

  •   

虽然函数模板的特化产生了带有标识转换的参数,但是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)

在您的特定情况下,应用的解决规则的相关部分是非模板函数优先于模板函数,这就是您看到指针而不是数组引用的原因。