c++ - 什么是模板推导指南,何时应使用它们?

标签 c++ templates c++17 c++-faq template-argument-deduction

C++ 17标准引入了“模板推导指南”。我认为它们与在该版本标准中引入的针对构造函数的新模板自变量推论有关,但是我还没有看到关于它们的含义和用途的简单的,常见问题解答风格的解释。

  • C++ 17中的模板推导指南是什么?
  • 为什么(何时)需要它们?
  • 如何声明它们?
  • 最佳答案

    模板推导指南是与模板类关联的模式,它们告诉编译器如何将一组构造函数参数(及其类型)转换为该类的模板参数。
    最简单的示例是std::vector及其采用迭代器对的构造函数。

    template<typename Iterator>
    void func(Iterator first, Iterator last)
    {
      vector v(first, last);
    }
    
    编译器需要弄清楚vector<T>T类型是什么。我们知道答案是什么; T应该是typename std::iterator_traits<Iterator>::value_type。但是我们如何告诉编译器而不必键入vector<typename std::iterator_traits<Iterator>::value_type>呢?
    您使用推论指南:
    template<typename Iterator> vector(Iterator b, Iterator e) -> 
        vector<typename std::iterator_traits<Iterator>::value_type>;
    
    这告诉编译器,当您调用与该模式匹配的vector构造函数时,它将使用vector右侧的代码推导->专门化。
    当从参数中推导类型不基于那些参数之一的类型时,您需要指南。从vector初始化initializer_list会明确使用vectorT,因此不需要指南。
    左侧不一定指定实际的构造函数。它的工作方式是,如果在类型上使用模板构造函数推导,则它将与针对所有推导指南传递的参数匹配(主模板的实际构造函数提供隐式指南)。如果存在匹配项,它将使用它来确定要提供给该类型的模板参数。
    但是一旦推论完成,一旦编译器找出了该类型的模板参数,就对该类型的对象进行初始化,就好像没有发生任何事情一样。也就是说,所选的推导指南不必与所选的构造函数匹配。
    这也意味着您可以将指南与汇总和汇总初始化结合使用:
    template<typename T>
    struct Thingy
    {
      T t;
    };
    
    Thingy(const char *) -> Thingy<std::string>;
    
    Thingy thing{"A String"}; //thing.t is a `std::string`.
    
    因此,推导仅用于确定要初始化的类型。一旦确定,初始化的实际过程便会像以前一样工作。

    关于c++ - 什么是模板推导指南,何时应使用它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64991788/

    相关文章:

    c++ - 澄清 P0137 的细节

    c++ - 使用来自两个列表的组合生成函数调用

    c++ - 常量引用有何不同?

    C++ 子结构

    c++ - C/C++ : Constant array of constant arrays

    c++ - 如何使用类模板删除样板代码?

    c++ - 对文件中的字符串进行排序

    c++ - 让 std::complex<double> 通过 std::is_floating_point 测试

    c++ - 错误 : expected unqualified-id before '<' token (Template compilation issue)

    c++ - 为什么我们在迭代可变模板参数时必须使用额外的构造?