什么是模板扣除指南,何时应该使用它们
What are template deduction guides and when should we use them?
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
,明确使用vector
的T
,因此它不需要指南。
左侧不一定指定实际的构造函数。它的工作方式是,如果您在类型上使用模板构造函数扣除,则它与您通过所有扣除指南的参数相匹配(主模板的实际构造函数提供隐式指南)。如果有匹配,它将使用它来确定要提供的模板参数。
但是,一旦完成,一旦编译器将类型的模板参数计算出来,该类型对象的初始化就会像没有发生一样。也就是说,所选的扣除指南不必匹配构造函数选择。
这也意味着您可以使用汇总的指南并进行汇总初始化:
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"}; //thing.t is a `std::string`.
因此,扣除指南仅用于找出初始化的类型。一旦做出确定,初始化的实际过程与以前完全一样。
- 何时应通过引用传递矢量参数而不是按值传递矢量参数?
- 何时应在构造函数参数中使用 const C++?
- 为什么或何时应在调用之前将可调用函数参数强制转换为右值?
- 点云库 (PCL) - 声明点云时何时应使用 ::P tr 的经验法则?
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- 记录器何时应刷新
- 何时应使用 [[maybe_unused]]
- 何时应在现代C++中使用(非标头)源文件
- 何时应使用模板化参数与构造参数
- 关键部分或静音是否真的是成员变量,或者何时应成为成员变量
- 何时应存储指向函数的引用或指针?
- 何时应在Qt中将子对象声明为其父类的成员变量
- 何时应找到附加到模型的边界框的最小值和最大值
- 何时应删除默认的移动构造函数时令人困惑的事情
- 何时应使用make_heap与优先级队列
- 何时应通过常量引用传递运算符重载函数的参数
- 何时应防止隐式销毁?它是如何工作的
- 何时应使用std::atomic_compare_exchange_strong
- 何时应在非成员函数之前编写关键字 'static'?
- 什么是"is-implemented-in-terms-of"关系,何时应使用它?