“Deduction guides” 在 C++17 标准 https://www.iso.org/standard/68564.html
中属于 17.9 章节. 标准中如下描述:
Deduction guides 用于将一个 模板名称 声明为一个类型标识符, 此时需要使用
Deduction guides 推导出该标识符的类型. Deduction guides 不使用名称查找,
而是使用模板参数推导, 所有为该模板名称声明的 deduction guides 都会作为推导依据.
语法
deduction-guide :
explicitopt template-name (parameter-declaration-clause) -> simple-template-id ;
在实际使用中, 可以为某个模板名称提供多个 deduction guides.
例子
例 1
// 声明了一个模板 S (1)
<template<class T, class D = int>
struct S {
T data;
};
// (2)
// 利用模板名称给出推导提示. 此例中, 若给定一个模板参数 U, 希望推导为
// S<typename U::type>. 隐含的约束是类型 U 必须内含一个类型名为 type
template<class U>
S(U) -> S<typename U::type>;
/* 应用上面的 deduction guides */
// 结构 A 中内含了类型名为 type
struct A {
using type = short;
operator type();
};
// 下面语句是单参数, 所以会选用 (2) 进行推导
// 在进行推导时, 发现 A::type 存在, 所以推导成功
// 使得 x 的类型为 S<short, int>
S x{A()};
例 2 两个 deduction guides
// 定义一个模板 SS (1)
template<typename T>
struct SS { T t; };
// 定义两个 deduction guides
SS(double) -> SS<double>; // (2)
SS(std::pair<int, int>) -> SS<std::pair<int, int>>; // (3)
// 按主模板 (1) 进行推导, s1 的类型为 SS<int>
SS s1{1};
// 按 (2) 进行推导, s2 的类型为 SS<double>
SS s2{1.5};
// 按 (3) 进行推导, s3 的类型为 SS<std::pair<int, int>>
std::pair<int, int> p{1,2};
SS s3{p};
最后
以前的文章 C++17 之 “利用构造函数推导模板参数类型”,
通过构造函数的参数类型推导出模板参数类型, 其中也有 Deduction guides 的功劳, 如
std::pair p(1, 1.5); // p 的类型为 std::pair<int, double>
std::tuple t(1, 2, 2.5); // t 的类型为 std::tuple<int, int, double>
std::vector v{1,2,3}; // v 的类型为 td::vector<int>
std::array a{1,2}; // a 的类型为 td::array<int, 2>