gpt4 book ai didi

c++ - 这个重载决议是否正确?

转载 作者:可可西里 更新时间:2023-11-01 15:22:31 24 4
gpt4 key购买 nike

发件人: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");
}

以上代码在使用 g++-4.9.0 -ansi -pedantic -std=c++11 编译时打印“char*”。

我觉得这是不正确的,因为字符串字面量的类型是“array of n const char”,应该不可能初始化一个非 const char* ,因此应该选择 std::string 重载。 gcc 是否违反了这里的标准?

最佳答案

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

2.14.5 String literals [lex.string]

7 A string literal that begins with u8, such as u8"asdf", is a UTF-8 string literal and is initialized with the given characters as encoded in UTF-8.
8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).
9 A string literal that begins with u, such as u"asdf", is a char16_t string literal. A char16_t string literal has type “array of n const char16_t”, where n is the size of the string as defined below; it has static storage duration and is initialized with the given characters. A single c-char may produce more than one char16_t character in the form of surrogate pairs.
10 A string literal that begins with U, such as U"asdf", is a char32_t string literal. A char32_t string literal has type “array of n const char32_t”, where n is the size of the string as defined below; it has static storage duration and is initialized with the given characters.
11 A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type “array of n const wchar_t”, where n is the size of the string as defined below; it has static storage duration and is initialized with the given characters.

接下来,让我们看看我们只有标准数组衰减,所以从 T[#]T*:

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

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

1.4 Implementation compliance [intro.compliance]

1 The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior.”
2 Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:

  • If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute2 that program.
  • If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
  • If a program contains a violation of a rule for which no diagnostic is required, this InternationalStandard places no requirement on implementations with respect to that program.

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

(在 C++11 (C++03) 之前,允许转换但已弃用,因此它应该是正确的。如果它发生,则不需要诊断,但作为实现质量问题提供。)

这是一个 GCC 错误(尚未找到错误报告),也是一个 clang bug (found by T.C.)。

来自 clang 错误报告的测试用例,它更短:

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

关于c++ - 这个重载决议是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24662385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com