什么是模板扣除指南,何时应该使用它们

What are template deduction guides and when should we use them?

本文关键字:何时应 什么      更新时间:2023-10-16

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专业化。

当从参数中扣除类型不是基于这些参数之一的类型时,您需要指南。从initializer_list初始化vector,明确使用vectorT,因此它不需要指南。

左侧不一定指定实际的构造函数。它的工作方式是,如果您在类型上使用模板构造函数扣除,则它与您通过所有扣除指南的参数相匹配(主模板的实际构造函数提供隐式指南)。如果有匹配,它将使用它来确定要提供的模板参数。

但是,一旦完成,一旦编译器将类型的模板参数计算出来,该类型对象的初始化就会像没有发生一样。也就是说,所选的扣除指南不必匹配构造函数选择。

这也意味着您可以使用汇总的指南并进行汇总初始化:

template<typename T>
struct Thingy
{
  T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"}; //thing.t is a `std::string`.

因此,扣除指南仅用于找出初始化的类型。一旦做出确定,初始化的实际过程与以前完全一样。