自动与字符串文字

fre*_*low 20 c++ type-inference string-literals auto c++11

#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";
}
Run Code Online (Sandbox Code Playgroud)

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

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

sel*_*tze 24

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

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

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

auto& x = "Hello world!";
Run Code Online (Sandbox Code Playgroud)

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

  • `auto && x ="Hello world!";`也是一种可能性(产生一个对数组的左值引用,就像`auto&`在这个例子中一样). (3认同)
  • @LucDanton对,我总是忘记字符串文字是左值. (2认同)

Naw*_*waz 5

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

由于数组到指针的转换。

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

const char m[]          = "ABC";

const char n[sizeof(m)] = m; //error
Run Code Online (Sandbox Code Playgroud)

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

const char* n = m; //ok
Run Code Online (Sandbox Code Playgroud)

类型推断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*
Run Code Online (Sandbox Code Playgroud)

§7.1.6.4/ 6关于auto说明符说:

然后为变量d推导的类型是根据函数调用(14.8.2.1)的模板参数推导规则确定的推导A ...