Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “的确切类型是什么?”&引用;当由“自动”推断时?_C++_C++11_Auto_C Strings - Fatal编程技术网

C++ “的确切类型是什么?”&引用;当由“自动”推断时?

C++ “的确切类型是什么?”&引用;当由“自动”推断时?,c++,c++11,auto,c-strings,C++,C++11,Auto,C Strings,在这方面: auto a = "Hello World"; a的确切类型是什么?我猜是char[]还是const char*const,但我不确定。N4296 2.13.5/8 还引用了普通字符串文字和UTF-8字符串文字 将其转换为窄字符串文字窄字符串文字的类型为“数组” n常量字符“,其中n是以下定义的字符串大小, 并且具有静态存储持续时间(3.7) 但由于变量是在代码中初始化的,它实际上是const char*,所以可以这样检查它 template<typename> str

在这方面:

auto a = "Hello World";
a
的确切类型是什么?我猜是
char[]
还是
const char*const
,但我不确定。

N4296 2.13.5/8

还引用了普通字符串文字和UTF-8字符串文字 将其转换为窄字符串文字窄字符串文字的类型为“数组” n常量字符“,其中n是以下定义的字符串大小, 并且具有静态存储持续时间(3.7)

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

template<typename> struct TD;

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

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

模板结构TD;
模板
空隙f(T)
{
TD_u2;;
}
int main()
{
自动c=“你好”;
TD_u2;;
f(“你好”);
}
类型为
TD
的两个实例化对象的类型均为
TD

N4926 14.8.2.1

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

如果p不是引用类型:

如果是数组类型,则为 使用数组到指针的标准转换(4.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)>();
}
检查
++a
是否编译是另一条线索(确实如此),虽然实现定义了
#include
/
typeid(a).name()
通常有助于回答此类问题


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

您可以使用
typeinfo

int main()
{
    auto a = "Hello World";
    std::cout << "type is: " << typeid(a).name() << '\n';
} 
intmain()
{
auto a=“你好,世界”;

std::如果这样,它会衰减为
const char*
看起来像
const char*
,在我的g++(4.8.1)版本中,既有
typeid(a).name()
又有
typeid(const char*)。name()
返回相同的值,而
typeid(const char[])。name()
typeid(b).name()
const char b[]=“Hello World”
)返回其他内容。“您可以像这样检查它
TD
”-这是如何检查的?不仅是
TD
不完整以致无法定义,而且如果修复了它,它将适用于任何类型-请参阅。@TonyD重点是,不完整的类型会触发编译器错误,从而打印出用于实例化此不完整类型的类型。更方便的解决方案是
template void TD(){std::cout@TonyD这是检查。不定义TD。您将在编译时将TD类型视为编译时错误。@您的注释也将是答案的良好扩展。这将使答案能够自我解释。“触发编译器错误,打印出用于实例化此不完整类型的类型”-哦-我想这对任何编译器都是正确的…好主意。干杯。使用c++filt来定义名称。无论如何,typeid不是显示类型的最佳方式,因为它丢弃了cv限定符。你是对的,我不知道,我被
char*b=const\u cast(a)这一事实弄糊涂了;std::cout我不推荐typeid.name,因为它可能返回错误的类型,正如Scott Meier在(幻灯片32)中所解释的那样
#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*
int main()
{
    auto a = "Hello World";
    std::cout << "type is: " << typeid(a).name() << '\n';
} 
#include <typeinfo>
std::cout << std::is_same<const char*, decltype(a)>::value << std::endl;