【问题标题】:Why does clang take a string literal as a pointer rather than an array?为什么 clang 将字符串文字作为指针而不是数组?
【发布时间】:2017-01-03 21:35:26
【问题描述】:
#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[]。

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

【问题讨论】:

  • 等价示例,但抽象出模板:@​​987654322@
  • Closely related,可能是骗子。你怎么看?

标签: c++ overloading standards string-literals


【解决方案1】:

它确实按预期运行,你只需要调整你的期望;-)

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

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

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

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

你会得到一个函数调用不明确的错误。

【讨论】:

  • 太慢了。 :(供参考,相关标准见N4141表12
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多