为什么clang将字符串文字作为指针而不是数组?

时间:2017-01-03 03:21:04

标签: c++ overloading standards string-literals

#include <iostream>
using namespace std;

void f(const char* arg)
{
    cout << "arg is a pointer" << endl;
}

template<size_t N>
void f(const char (&arg)[N])
{
    cout << "arg is an array." << endl;
}

int main()
{
    f("");
}

我的编译器是clang 3.8。

输出结果为:

  

arg是一个指针

然而,根据cppreference.com

  

未加前缀的字符串文字的类型是const char []。

为什么重载决策的行为不符合预期?

2 个答案:

答案 0 :(得分:8)

它表现得像预期的那样,你只需要调整你的期望; - )

const char[1]const char (&)[1]是不同的类型。

转换为const char*(数组到指针转换)和const (&char)[1](身份转换)都被认为是完全匹配,但非模板比模板更匹配。

如果您编写非模板大小特定的重载,

void f(const char (&arg)[1])

您将收到函数调用不明确的错误。

答案 1 :(得分:1)

@ molbdnilo的回答是正确的。添加一个细节:你的直觉是正确的,编译器更愿意通过调用模板来避免数组到指针的转换。但是根据[over.ics.rank]§13.3.3.2/ 3.2.1,在重载排名中特别忽略左值变换(左值到右值,数组到指针和函数到指针)。

有一个workaround:添加假volatile来恢复重载偏好的平衡。在使用参数之前,请务必将其const_cast删除。