【发布时间】:2021-04-18 15:51:36
【问题描述】:
#include <iostream>
#define FUNC() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
void foo(char const*&& ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B
int main()
{
foo("bar");
}
当在第一个重载 (A) 的参数类型中使用右值引用时,clang 当前主机明确地选择重载 A 而不是 B。另一方面,GCC 当前主机抱怨有歧义。
我很惊讶字符串文字是 4 char const 的左值([expr.prim.literal]/1,[lex.string]/6)应该更喜欢重载 A 上的数组到指针转换重载 B 上的恒等式转换。
如果没有右值引用,即void foo(char const*),GCC 和 clang 都会因为不明确而拒绝调用。这也是我不完全理解的事情,因为我猜到仍然存在数组到指针的转换,因此 [over.ics.rank]p3.2.1 适用:
标准转换序列S1是比标准转换序列S2更好的转换序列如果
- (3.2.1) S1 是 S2 的适当子序列(比较 [over.ics.scs] 定义的规范形式的转换序列,不包括 任何左值变换;身份转换序列是 被认为是任何非身份转换的子序列 序列),或者,如果不是,
这两种情况发生了什么?
【问题讨论】:
-
这个问题看起来很熟悉,但我不知道如何搜索 SO...
-
也许 clang 看着 eel.is/c++draft/over#ics.rank-3.2.3 并说,衰减的字符串文字是一个右值......?
-
如果没有右值引用,即 void foo(char const*),GCC 和 clang 都会因为不明确而拒绝调用。这也是我不太明白的地方 CWG1789
标签: c++ language-lawyer implicit-conversion overload-resolution