当由“auto”推断时,“”的确切类型是什么?

时间:2015-08-19 07:33:49

标签: c++ c++11 auto c-strings

在这一行:

auto a = "Hello World";

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

3 个答案:

答案 0 :(得分:10)

N4296 2.13.5 / 8

  

也引用普通的字符串文字和UTF-8字符串文字   作为窄字符串文字。 窄字符串文字的类型为“数组”   of n const char“,其中n是下面定义的字符串的大小,   并具有静态存储时间(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

  

如果占位符是自动类型说明符,则推导出的类型为   使用模板参数推导规则确定。

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

  

通过比较每个函数来完成模板参数推导   模板参数类型(称之为P)与对应的类型   呼叫的参数(称之为A)如下所述。

     

如果P不是参考类型:

     

如果A是数组类型,则由指针类型生成   使用数组到指针标准转换(4.2)代替A for   类型扣除

答案 1 :(得分:2)

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

#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的{​​{1}}更改。

答案 2 :(得分:1)

您可以使用typeinfo

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

在gcc上会打印

  

pi是:PKc

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

如果你或多或少知道你需要找哪种类型,你也可以检查两种类型是否相同:

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