在这一行:
auto a = "Hello World";
a
的完全类型是什么?我猜是char[]
或const char* const
,但我不确定。
答案 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
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;