C++ 什么是模板演绎指南?我们应该在什么时候使用它们?

C++ 什么是模板演绎指南?我们应该在什么时候使用它们?,c++,templates,c++17,c++-faq,template-argument-deduction,C++,Templates,C++17,C++ Faq,Template Argument Deduction,C++17标准引入了“模板推导指南”。我推测它们与此版本标准中引入的构造函数的新模板参数推断有关,但我还没有看到一个简单的、FAQ风格的解释,说明它们是什么以及它们的用途 C++17中的模板推导指南是什么 我们为什么(何时)需要它们 如何申报 模板推导指南是与模板类关联的模式,它告诉编译器如何将一组构造函数参数(及其类型)转换为该类的模板参数 最简单的例子是std::vector及其采用迭代器对的构造函数 template<typename Iterator> void func(

C++17标准引入了“模板推导指南”。我推测它们与此版本标准中引入的构造函数的新模板参数推断有关,但我还没有看到一个简单的、FAQ风格的解释,说明它们是什么以及它们的用途

  • C++17中的模板推导指南是什么

  • 我们为什么(何时)需要它们

  • 如何申报


模板推导指南是与模板类关联的模式,它告诉编译器如何将一组构造函数参数(及其类型)转换为该类的模板参数

最简单的例子是
std::vector
及其采用迭代器对的构造函数

template<typename Iterator>
void func(Iterator first, Iterator last)
{
  vector v(first, last);
}
这告诉编译器,当您调用与该模式匹配的
向量
构造函数时,它将使用
->
右侧的代码推断
向量
专门化

当从参数中推断类型不是基于其中一个参数的类型时,您需要指南。从
初始值设定项列表
初始化
向量
显式使用
向量
T
,因此它不需要指南

左侧不一定指定实际的构造函数。它的工作方式是,如果对类型使用模板构造函数推断,它将匹配针对所有推断指南传递的参数(主模板的实际构造函数提供隐式指南)。如果存在匹配项,它将使用该匹配项确定要向类型提供哪些模板参数

但一旦推导完成,一旦编译器计算出该类型的模板参数,该类型对象的初始化就会继续进行,就好像没有发生任何情况一样。也就是说,所选的扣减指南不必与所选的构造函数匹配

这也意味着您可以将指南用于聚合和聚合初始化:

template<typename T>
struct Thingy
{
  T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.
模板
结构物
{
T;
};
Thingy(const char*)->Thingy;
东西{“一串”}//t是一个'std::string'。

因此,演绎指南仅用于确定要初始化的类型。一旦确定,初始化的实际过程与以前完全一样。

特别是,我想知道C++17 STL是否实际提供了任何演绎指南(例如,对于std::pair或std::tuple)。从C++17开始,“可推断”标准模板类型的完整列表是什么?@Quuxplusone和我想知道是否有编译器支持这一点。我试过gcc、clang和vc++。不过,我发现它只适用于gc++8.1 C++17和2a g++-std=C++17-O2-Wall-pedantic-pthread main.cpp&./a.outHmm,我突然想到,即使有了指南,
vector v{first,last}
不会做正确的事情:(@t.C….除非正确的事情是生成迭代器的向量。并且
std::string{32,'*'}[0]=''
(对于ASCII)。但是从C++11开始这一切都是正确的。分配器向量参数会发生什么?如果分配器向量参数没有默认参数,会发生什么?(你不能从InputIterator中推断出来)@Nicolas:你介意解释一下隐式和显式推断指南如何在部分或完全专业化的类(其构造函数显然不必具有与主模板匹配的参数类型)的上下文中工作吗?通过快速搜索很难找到这方面的信息。@Nicolas:我明白了。我不清楚这个问题到底是关于明确的推断指南的……我认为如果你只在这篇评论中包含你字面上写的内容,这会很有帮助。
template<typename T>
struct Thingy
{
  T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.