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;