由 `auto` 推导时,"" 的确切类型是什么?

What is the exact type of "" when deduced by `auto`?

这一行:

auto a = "Hello World";

a 确切 类型是什么?我猜是 char[]const char* const,但我不确定。

N4296 2.13.5/8

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).

但是由于变量在您的代码中被初始化,它实际上是 const char*,您可以这样检查它。

template<typename> struct TD;

int main()
{
   auto a = "Hello World";
   TD<decltype(a)> _;
}

这里会出现编译错误,您可以在其中看到 TD 实例的实际类型,类似于 clang

error: implicit instantiation of undefined template 'TD<const char *>'

N4296 7.1.6.4

If the placeholder is the auto type-specifier, the deduced type is determined using the rules for template argument deduction.

template<typename> struct TD;

template<typename T>
void f(T) 
{
   TD<T> _;
}

int main()
{
   auto c = "Hello";
   TD<decltype(c)> _;
   f("Hello");
}

类型 TD 的两个实例化对象都具有类型 TD<const char*>.

N4926 14.8.2.1

Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below.

If P is not a reference type:

If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction

除非您有理由认为它是实现的或未定义的,否则可以测试:

#include <iostream>

template <typename T> void f() { std::cout << "other\n"; }
template <> void f<const char*>() { std::cout << "const char*\n"; }
template <> void f<const char* const>()
    { std::cout << "const char* const\n"; }
template <> void f<const char(&)[12]>() { std::cout << "const char[12]\n"; }

int main()
{
    auto a = "Hello World";
    f<decltype(a)>();
}

输出:

const char*

检查 ++a 编译是另一条线索(确实如此),虽然实现定义 #include <typeinfo> / typeid(a).name() 通常可以帮助回答此类问题。

更改为 auto& a,您将看到 a 更改为 const char(&)[12]

您可以使用 typeinfo

打印 a 的类型
int main()
{
    auto a = "Hello World";
    std::cout << "type is: " << typeid(a).name() << '\n';
} 

在 gcc 上它将打印

pi is: PKc

表示指向常量char的指针 如果你在 Windows 中,输出将更具可读性,但你也会习惯这种语法。

如果您或多或少知道您要查找的是哪种类型,您还可以检查两种类型是否等同于:

#include <typeinfo>
std::cout << std::is_same<const char*, decltype(a)>::value << std::endl;