这种重载分辨率是否正确?

时间:2014-07-09 19:37:54

标签: c++ c++11 language-lawyer overload-resolution

来自:Is it safe to overload char* and std::string?

#include <string>
#include <iostream>
void foo(std::string str) {
  std::cout << "std::string\n";
}

void foo(char* str) {
  std::cout << "char*\n";
}

int main(int argc, char *argv[]) {
  foo("Hello");
}

以上代码打印&#34; char *&#34;使用g++-4.9.0 -ansi -pedantic -std=c++11编译时。

我觉得这是不正确的,因为字符串文字的类型是&#34; n const char&#34;的数组,它不应该是可以用它来初始化非const char*,因此应该选择std::string重载。 gcc是否违反了标准?

1 个答案:

答案 0 :(得分:7)

首先,字符串文字的类型:它们都是字符类型的常量数组。

  

2.14.5字符串文字[lex.string]

     

7以u8开头的字符串文字,例如u8&#34; asdf&#34;,是一个UTF-8字符串文字,并使用UTF-8编码的给定字符进行初始化。
  8普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char数组”,其中n是下面定义的字符串大小,并且具有静态存储持续时间(3.7)。
  9以u开头的字符串文字,例如u&#34; asdf&#34;,是一个char16_t字符串文字。 char16_t字符串文字的类型为“n const char16_t的数组”,其中n是下面定义的字符串的大小;它具有静态存储持续时间,并使用给定的字符进行初始化。单个c-char可以以代理对的形式产生多个char16_t字符   10以U开头的字符串文字,例如U&#34; asdf&#34;,是一个char32_t字符串文字。 char32_t字符串文字的类型为“n const char32_t的数组”,其中n是下面定义的字符串的大小;它具有静态存储持续时间,并使用给定的字符进行初始化   11以L开头的字符串文字,例如L&#34; asdf&#34;,是一个宽字符串文字。宽字符串文字的类型为“n const wchar_t的数组”,其中n是字符串的大小,如下所示;它具有静态存储持续时间,并使用给定的字符进行初始化。

接下来,我们看到我们只有标准数组衰减,因此从T[#]T*

  

4.2数组到指针的转换[conv.array]

     

1类型为“N T数组”或“未知T的数组”的左值或右值可以转换为“指向T的指针”类型的prvalue。结果是指向数组的第一个元素的指针。

最后,让我们看看任何符合标准的扩展都不能改变正确程序的含义:

  

1.4实施合规性[intro.compliance]

     

1可诊断规则集包含本国际标准中的所有语法和语义规则,但那些包含“无需诊断”的明确表示法或描述为“未定义行为”的规则除外。
  2虽然本国际标准仅规定了对C ++实现的要求,但如果将这些要求表达为对程序,程序部分或程序执行的要求,则这些要求通常更容易理解。这些要求具有以下含义:

     
      
  • 如果某个程序不违反本国际标准中的规则,则符合条件的实施应在其资源限制内接受并正确执行该程序。
  •   
  • 如果程序包含违反任何可诊断规则或本标准中描述的构造的发生,如果实现不支持该构造,则符合条件的实现应发出至少一条诊断消息。 / LI>   
  • 如果某个程序违反了不需要诊断的规则,则为国际   标准对该程序的实施没有要求。
  •   

因此,总而言之,它是一个编译器错误。

(在C ++ 11(C ++ 03)之前,转换是允许的但是已弃用,所以它本来是正确的。如果发生这种情况的诊断不是必需的,而是作为实施质量问题提供的。)

这是一个海湾合作委员会的错误,也是一个铿锵的错误 clang的错误报告:http://llvm.org/bugs/show_bug.cgi?id=16314Thanks to T.C. for finding the bug report.

来自clang bug-report的测试用例,它更短:

void f(char*);
int &f(...);
int &r = f("foo");