【问题标题】:Why does "auto" declare strings as const char* instead of std::string?为什么“auto”将字符串声明为 const char* 而不是 std::string?
【发布时间】:2014-01-01 14:05:38
【问题描述】:

我制作了一个模板,它添加了给定的数据。如果我这样使用,编译器会将 in_1 和 in_2 声明为 const char *,代码无法编译。

#include <iostream>
using namespace std;
template <class T>
T addstuff(T part_1, T part_2){
    return(part_1+part_2);
}

int main(int argc, char const *argv[])
{
    auto in_1="Shut ";
    auto in_2="up.";
    cout<<addstuff(in_1, in_2)<<endl;
    return 0;
}

如果我声明 in_1 和 in_2 std::string,它就像一个魅力。

为什么编译器不能(或不)自动声明这些字符串 std::string?

【问题讨论】:

  • 为什么会这样?它们的类型不是std::string 而是const char (&amp;)[N + 1](N 是字符串的长度)。
  • 这就是我们需要字符串文字 (en.cppreference.com/w/cpp/string/basic_string/operator%22%22s) 的原因。一个令人困惑的问题,但它显示了人们对 C++ 的期望有多远(以及它对初学者的友好程度)。
  • 为了它的价值:您可以在 C++11 中将字符串文字后缀自己实现为 _s;无需等待。 std::string operator"" _s(const char * str, size_t len) { return std::string{str, len}; }

标签: c++ string c++11 auto


【解决方案1】:

您不能“写入”到您的自动变量的原因是它是一个 const char * 或 const char [1],因为这是任何字符串常量的类型。

auto 的重点是解析为最简单的可能类型,该类型对分配类型“有效”。编译器不会“期待看到你对变量做了什么”,所以它不明白稍后你会想要写入这个变量,并用它来存储一个字符串,所以 std::string 会更有意义。

可以使您的代码以多种不同的方式工作,这是一种有意义的方式:

std::string default_name = "";
auto name = default_name;

cin >> name;

【讨论】:

  • 您可能希望将第一段中的“字符串常量”更改为“字符串文字”,因为字符串常量可能被合理地理解为常量std::string
【解决方案2】:

因为字符串文字的类型为const char[N+1],而不是std::string

这只是语言的事实。

他们本可以让auto 对字符串文字有一个特殊情况,但这会不一致、令人惊讶并且几乎没有什么好处。

【讨论】:

  • 如果这个答案也能解释为什么in_1 没有const char[6] 类型,那就太好了
【解决方案3】:

如果您使用字符串文字,auto 将按预期工作。

在 C++14、C++17 或 C++20 中,您可以在引号后放置 s,它将创建一个 std::string 而不是 const char* 字符串。

这可以和auto一起使用来创建一个std::string

auto hello = "hello"s;

默认情况下不启用字符串文字。启用字符串文字的一种方法是将以下内容放在源文件的顶部:

#include <string>
using namespace std::string_literals;  

例如,此循环适用于std::string(将s 添加到字符串文字中),但不适用于const char* 类型的字符串文字:

for (auto &x : hello) {                                                                        
    std::cout << "letter: " << x << std::endl;                                                         
}

这里是the ""s operator 的 cppreference 页面。

【讨论】:

    【解决方案4】:

    auto 会将变量声明为您初始化它的表达式的编译时类型。

    字符串文字的类型是 const char*,而不是 std::string

    【讨论】:

    • @H2CO3 没有参考。
    • 准确来说,字符串字面量的类型是const char [length + 1],但它们当然会衰减为指针。
    猜你喜欢
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2018-08-10
    • 2013-11-06
    • 2011-05-26
    • 1970-01-01
    相关资源
    最近更新 更多