【ModernCpp】新特性之CTAD代码示例

描述

最近在阅读C++ Templates 2nd,发现有些很有意思的新特性,今天,借助本文,分享给大家。

从一个例子入手

首先,我们看如下例子:

 

template 
class Add{
 public:
  Add(T first, T second): first_{first}, second_{second} {}
  T result()const{return first + second;}
 private:
  T first_;
  T second_;
};

这个例子很简单,声明一个模板类Add,接收类型为T的构造函数Add,以及一个返回operator+结果的result()函数。

在c++17之前,如果我们要使用Add类,往往必须像如下这么做:

int main(){
  Add ti(1,2);
  return 0;
}

即在实例化对象ot的时候必须指明类型int

自C++17起引入了新的特性Class Template Argument Deduction,简称为CTAD,即类模板参数推导,那么就可以像如下这样实例化ADD类:

int main(){
  Add ti(1,2);               //T 被推导为int
  Add td{1.245, 3.1415};     //T 被推导为double
  Add tf = {0.24f, 0.34f}; //T 被推到位float
  return 0;
}

用例

上面的例子,我们已经体会到了CTAD带来的好处(代码间接),下面结合在项目中的用的例子更进一步的来说明CTAD。

相比我们都知道std::lock_guard类,其主要用了实现RAII功能,尤其在多线程环境中用的最多,如下:

std::mutex m;
std::recursive_timed_mutex rm;

void fun1(){
    std::lock_guard lg{m};
    //do sth
}

void fun2(){
    std::lock_guard lg{rm};
    //do sth
}

在C++17,我们往往得像上面这样写,即需要显式指定lock_guard的类型。但是,自C++17起,可以像如下这样写:

 

std::mutex m;
std::recursive_timed_mutex rm;

void fun1(){
    std::lock_guard lg{m};
    //do sth
}

void fun2(){
    std::lock_guard lg{rm};
    //do sth
}

显然,代码更加简洁统一。

限制

虽然CTAD用起来很方便,但是相对于不使用CTAD特性,有时候CTAD会存在一些问题,即编译器推导的类型并不是我们所预期的,仍然使用第一节中的例子:

int main() {
  Add ts("hello, ", "world!
");
  auto ret = ts.result();
  
  return 0;
}

在编译阶段,会报如下错误:

error: invalid operands of types 'const char* const' and 'const char* const' to binary 'operator+'
T result()const{return first_ + second_;}

即编译器会将"hello "和"world! "推导成为const char const,而c++的char是不支持operator+操作的,这就导致了上面的编译错误。

此时,我们可以使用C++17之前的实例方法即显示指明类型,如下:

int main() {
  Add ts("hello, ", "world!
");
  auto ret = ts.result();
  
  return 0;
}

如果这样做的话,多少有点失去了CTAD的好处,为了解决这种类似的问题,C++17支持显示类型推导,即添加代码:

Add(const char*, const char*) -> Add;

需要注意的是,这一行类型推导需要加在类声明之后,这样编译器在遇到参数为const cha*的时候,会自动将其推导为std::string.

这样,我们的例子最后如下:

Add(const char*, const char*) -> Add;
int main() {
  Add ts("hello ", " world!
");
  ts.result();
}

以上~~

审核编辑:黄飞

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分