【问题标题】:What is the difference between auto deduction and template type deduction?自动扣款和模板扣款有什么区别?
【发布时间】:2019-02-01 09:48:37
【问题描述】:

让我们有以下代码

    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幕后输入?

【问题讨论】:

  • 引用参考文献是一个好习惯,尤其是当您逐字使用内容时。来自 Scott Meyers 的“Effective Modern C++”。
  • 分享知识是件好事。但是您必须提及您的来源,尤其是在涉及使用已出版的受版权保护书籍的内容时。
  • 这不是我幸福的问题。受版权保护的材料可以被删除。例如看这篇文章。 meta.stackoverflow.com/questions/276012/…
  • 自动类型推导与模板类型推导相同,但花括号初始化器除外。 Scott Meyers 在下面的 cppcon youtu.be/wQxj20X-tIU 中已经清楚地解释了这一点

标签: c++ templates auto


【解决方案1】:

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&lt;T&gt; 对于一些未知的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,模板类型推导不行。

【讨论】:

  • 引用参考文献是一个好习惯,尤其是当您逐字使用内容时。来自 Scott Meyers 的“Effective Modern C++”。
  • 分享知识是件好事。但是您必须提及您的来源,特别是如果它涉及使用已出版的受版权保护书籍的内容。
  • 如果整个答案是引用,那么整个答案应该是引用格式。这不是你的工作!
  • @P.W 编辑引用格式,然后忽略抄袭者。看不到聊天实现任何目标的方法。 IME 这是一种文化的东西(直到你在 SE 上发帖,你才会受到政策和合法性的约束)
【解决方案2】:

Auto type deduction 采用不同的列表初始化规则。使用copy-list-initialization,模板参数P被认为是std::initializer_list&lt;U&gt;

(强调我的)

参数P的获取方式如下:在T中,包含auto的变量的声明类型,每次出现auto都替换为一个虚构的类型模板参数U或者,如果初始化为copy-list-初始化,std::initializer_list&lt;U&gt;。参数 A 是初始化表达式。

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

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

在direct-list-initialization(而不是copy-list-initialization)中,当从braced-init-list推导出auto的含义时,braced-init-list必须只包含一个元素,并且类型of 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>)

【讨论】:

    猜你喜欢
    • 2017-08-08
    • 2019-06-06
    • 2017-02-17
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2019-06-30
    相关资源
    最近更新 更多