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/47856153/

相关文章:

c++ - 在 C++17 中弃用 `std::result_of` 的原因是什么?

python - Jinja2 模板 - for 循环

c++ - 交换和 move 无限递归

c++ - 如何将变量的元素转换为 std::string ( c++ )

c++ - 对泛型函数使用继承

c++ - 编译 Fast Light Toolkit (FLTK) 2.0 以与 fastHOG 一起使用

C++ 模板类 : template paramaters given at runtime, 如何避免重复的大型开关案例?

c++ - std::lock_guard 还是 std::scoped_lock?

c++ - 非模板代码有效时,模板代码无效!

c++ - 在 lambda 中通过引用捕获 unique_ptr 如何正常工作?