自动演绎和模板类型演绎有什么区别?

时间:2019-02-01 09:48:38

标签: c++ templates auto

让我们输入以下代码

    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在幕后是什么类型?

2 个答案:

答案 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>)