#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 []。
为什么重载决策的行为不符合预期?
答案 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
删除。