21
#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]

4

3 回答 3

25

该功能auto基于模板参数推导,模板参数推导行为相同,具体根据 §14.8.2.1/2(C++11 标准):

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

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

auto& x = "Hello world!";

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

于 2012-08-18T08:09:01.480 回答
6

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

因为数组到指针的转换。

Ifx被推导出为数组,仅当允许以下情况:

const char m[]          = "ABC";

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

在 C++ 中,不能用另一个数组(如上)初始化一个数组。在这种情况下,源数组会衰减为指针类型,您可以这样做:

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 推导的类型然后是使用从函数调用 (14.8.2.1) 的模板参数推导规则确定的推导 A ...

于 2012-08-18T07:49:26.780 回答
-1

如果您希望将 x 推导出为数组,您可以使用

decltype(auto) x = "hello world";
于 2020-05-17T17:15:01.893 回答