为什么 clang 将字符串文字作为指针而不是数组?
Why does clang take a string literal as a pointer rather than an array?
#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 is a pointer
然而,根据 cppreference.com,
The type of an unprefixed string literal is const char[].
为什么重载解析没有按预期运行?
它确实按预期运行,你只需要调整你的期望;-)
const char[1]
和const char (&)[1]
是不同的类型。
到const char*
(数组到指针的转换)和const (&char)[1]
(身份转换)的转换都被认为是完全匹配,但非模板比模板更匹配。
如果你写一个非模板大小特定的重载,
void f(const char (&arg)[1])
你会得到函数调用不明确的错误。
@molbdnilo 的回答是正确的。添加一个细节:您的直觉是正确的,编译器更愿意通过调用模板来避免数组到指针的转换。但是根据 [over.ics.rank] §13.3.3.2/3.2.1.
有一个workaround:添加一个假的volatile
来恢复过载偏好的平衡。请务必在使用参数之前通过 const_cast
将其删除。
#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 is a pointer
然而,根据 cppreference.com,
The type of an unprefixed string literal is const char[].
为什么重载解析没有按预期运行?
它确实按预期运行,你只需要调整你的期望;-)
const char[1]
和const char (&)[1]
是不同的类型。
到const char*
(数组到指针的转换)和const (&char)[1]
(身份转换)的转换都被认为是完全匹配,但非模板比模板更匹配。
如果你写一个非模板大小特定的重载,
void f(const char (&arg)[1])
你会得到函数调用不明确的错误。
@molbdnilo 的回答是正确的。添加一个细节:您的直觉是正确的,编译器更愿意通过调用模板来避免数组到指针的转换。但是根据 [over.ics.rank] §13.3.3.2/3.2.1.
有一个workaround:添加一个假的volatile
来恢复过载偏好的平衡。请务必在使用参数之前通过 const_cast
将其删除。