自动推导和模板类型推导有什么区别?

What is the difference between auto deduction and template type deduction?

让我们有以下代码

    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 类型推导假定大括号初始化器表示 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

但是,如果您在模板中指定参数是 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>

Remember

  • auto type deduction is usually the same as template type deduction, but auto type deduction assumes that a braced initializer represents a std::initializer_list, and template type deduction doesn’t.

Auto type deduction 采用不同的列表初始化规则。使用复制列表初始化,模板参数 P 被视为 std::initializer_list<U>.

(强调我的)

The parameter P is obtained as follows: in T, the declared type of the variable that includes auto, every occurrence of auto is replaced with an imaginary type template parameter U or, if the initialization is copy-list-initialization, with std::initializer_list<U>. The argument A is the initializer expression.

那么对于 auto x = { 11, 23, 9 };x 的类型将是 std::initializer_list<int>

对于直接列表初始化,规则不同:

In direct-list-initialization (but not in copy-list-initalization), when deducing the meaning of the auto from a braced-init-list, the braced-init-list must contain only one element, and the type of auto will be the type of that element:

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