为什么 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 将其删除。