演讲人是Stephan T. Lavavej ,负责msvc stl的

这个演讲的主题就是Class template argument deduction,简称CTAD,之前也接触过。借这个ppt彻底顺一下


简而言之这个c++17新特性给了类模板像函数模板一样的推导能力,可以省去指定参数,让编译器帮你推导

std::vector v{2}; //推导成vector<size_t>
lock_guard l(mtx); //推导成lock_guard<mutex>

还有pair,tuple 以及智能指针,以及guard,从此make_函数基本可以下岗

对比函数模板的推导,为什么类模板之前没有推导,以pair举例

  • 可能推导的类型很多
    • pair<int, int> p(11,22); 如果不指定int,有可能是long,类型很多
    • 解决办法,make_pair,通过函数模板转发和退化forwarding and decay
      • 缺点,低效,是个函数调用,调试烦人,且很繁琐(其实还行吧,多打个make_)

基本语法 初始化(){},直接初始化和赋值初始化

应用的场景

  • 容器,包括pair和tuple

    • 容器的范围初始化

      list<pair<int, string>> lst; 
      ...;//添加元素等等
      vector v(lst.begin(),lst.end());
      
  • lock_guard

  • functor 比如sort中的greater<\void>{}

遇到的错误以及引起的原因

pair p{};// 无法推导类型,不像上面的greater, 没有默认参数
array arr = {1,2,3.14};//推导不出个数
shared_ptr sp(new string);//由于数组指针的退化,这个指针类型区分不出是数组指针还是普通指针,shared_ptr<string> shared_ptr<string []>

上面的例子也引入了,缺少信息和歧义的推导条件会错误,这和函数模板类似

  • P1021提案 设计的场景可以fix
  • 别名模板,显式模板参数这两个场景无法使用CTAD
  • 需要推导指引,比如array,继承构造函数
推导指引

比如字符串,类型很容易推导成char[N] ,如果想要string,就需要写推导指引规则

能构造不等于能推导
template <typename A, typename B> 
struct Peppermint{
    explicit Peppermint(const A&){}
};
Peppermint<int, double> p1{11};
Peppermint p2{22};//err

第二种情况缺少了参数,也没有提示参数,推导不出来

再比如指针

template <typename A, typename B>
struct jazz{
    jazz(A*, B*){}
};
int i = 1;
const double d = 3.14;
jazz j1{&i, &d};
jazz j2{&i, nullptr};//err
  • CTAD自动推导原则:模板参数构造中都带上了,或者有默认的
  • 不能自动推导的原因
    • 模板参数没带上
    • 提供的参数没有帮助推导的额外信息 nullptr
    • 参数不可推导 list<T>::iterator

一个推导规则

template <typename T>
struct MyVec{
    template <typename It> MyVec(It,It){}
};
template <typename it> MyVec(It,It) -> MyVec<typename iterator_traits<It>::value_type>;//建立关系
int *ptr = nullptr;
MyVec v(ptr,ptr);
  • 如果是转发构造呢,CTAD是支持的,而make_函数有退化

值退化

reference

  1. https://zh.cppreference.com/w/cpp/language/class_template_argument_deduction
  2. 之前也提到过这个东西https://wanghenshui.github.io/2018/08/17/overload-trick
  3. ppt地址 https://github.com/CppCon/CppCon2018/tree/master/Presentations/class_template_argument_deduction_for_everyone

contact