让我们输入以下代码
auto x = { 11, 23, 9 };
template<typename T> // template with parameter
void f(T param);
f({ 11, 23, 9 }); // error! can't deduce type for T
以下代码auto
是自动推导的,而模板不是自动推导的。
如何推导auto
类型?
auto
在幕后是什么类型?
答案 0 :(得分:7)
auto
类型推导通常与模板类型推导相同,但是auto
类型推论假设括号初始化器代表std::initializer_list
,而模板类型推导则不。
用{}声明的变量auto
初始化时
支撑初始化程序,推导类型为std::initializer_list
的实例化。
但是,如果将相应的模板传递给相同的初始化程序,则类型推导将失败,
并且代码被拒绝:
auto x = { 11, 23, 9 }; // x's type is
//std::initializer_list<int>
template<typename T> // template with parameter
void f(T param); // template with parameter
但是,如果您在模板中指定param是std::initializer_list<T>
对于某些未知的T,模板类型推导将得出T是什么:
template<typename T>
void f(std::initializer_list<T> initList);
f({ 11, 23, 9 }); // T deduced as int, and initList's
// type is std::initializer_list<int>
记住
- 自动类型推导通常与模板类型推导相同,但是自动类型推导假定支撑初始化器表示一个
std::initializer_list
,而模板类型推导则没有。
答案 1 :(得分:1)
Auto type deduction采用不同的规则进行列表初始化。使用复制列表初始化时,模板参数 P 被视为std::initializer_list<U>
。
(重点是我的)
按以下方式获得参数P:在T中,声明的包括auto在内的变量的类型,每次出现的auto都用虚构的类型模板参数U代替;如果初始化为copy-list-,则
std::initializer_list<U>
进行初始化。参数A是初始化程序表达式。
然后对于auto x = { 11, 23, 9 };
,x
的类型为std::initializer_list<int>
。
对于直接列表初始化,规则如下:
在直接列表初始化中(但不是在复制列表初始化中),当从大括号初始列表推导auto的含义时,大括号初始列表必须仅包含一个元素,并且类型auto将会是该元素的类型:
auto x1 = {3}; // x1 is std::initializer_list<int> auto x2{1, 2}; // error: not a single element auto x3{3}; // x3 is int // (before N3922 x2 and x3 were both std::initializer_list<int>)