为什么自动变量在用字符串初始化时会推导为指针?

问题描述 投票:0回答:3
#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
会被推断为指针?

窄字符串文字的类型为“array of n

const char
”[2.14.5 字符串文字 [lex.string] §8]

c++ c++11 type-inference auto string-literals
3个回答
24
投票

功能

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

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

如果希望表达式

x
的类型为数组类型,只需在
&
后添加
auto
即可:

auto& x = "Hello world!";

然后,

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


6
投票

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

因为数组到指针的转换。

如果要将

x
推导为数组,仅当允许以下情况时:

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


-1
投票

如果你想把x推导为数组,你可以使用

decltype(auto) x = "hello world";
© www.soinside.com 2019 - 2024. All rights reserved.