自动与字符串文本

auto with string literals

本文关键字:文本 字符串      更新时间:2023-10-16
#include <iostream>
#include <typeinfo>
int main()
{
    const char a[] = "hello world";
    const char * p = "hello world";
    auto x = "hello world";
    if (typeid(x) == typeid(a))
        std::cout << "It's an array!n";
    else if (typeid(x) == typeid(p))
        std::cout << "It's a pointer!n";   // this is printed
    else
        std::cout << "It's Superman!n";
}

当字符串文字实际上是数组时,为什么x被推导为指针?

窄字符串文本的类型为">n const char数组" [2.14.5 字符串文本 [lex.string] §8]

基于模板参数推导的功能auto和模板参数推导的行为相同,特别是根据 §14.8.2.1/2(C++11 标准(:

  • 如果 P 不是引用类型
      如果 A 是数组类型
    • ,则使用数组到指针转换生成的指针类型代替 A 进行类型推断

如果您希望表达式x的类型是数组类型,只需在auto后添加&

auto& x = "Hello world!";

然后,auto占位符将被推断为const char[13]。这也类似于将引用作为参数的函数模板。为了避免任何混淆:声明的 x 类型将是引用数组。

当字符串文字实际上是数组时,为什么 x 被推导为指针?

因为数组到指针的转换。

如果要将x推导为数组,则仅当允许以下情况时:

const char m[]          = "ABC";
const char n[sizeof(m)] = m; //error

在C++中,一个arrray不能用另一个数组初始化(如上所示(。在这种情况下,源数组将衰减为指针类型,您可以改为执行此操作:

const char* n = m; //ok

使用 auto 进行类型推断的规则与函数模板中的类型推断规则相同:

template<typename T>
void f(T n);
f(m);     //T is deduced as const char*
f("ABC"); //T is deduced as const char*
auto n = m;     //n's type is inferred as const char*
auto n = "ABC"; //n's type is inferred as const char*

§7.1.6.4/6 说auto说明符:

然后,为变量 d 推导的类型是使用从函数调用中推导的模板参数推导规则确定的 A (14.8.2.1( ...

如果你想把

x推导为数组,你可以使用

decltype(auto) x = "hello world";