最近在阅读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();} 以上~~
如何焊接SOP或微型表面贴装芯片
三极管的放大倍数如何计算
中兴天机Axon旗舰传来好消息
戴尔XPSONE一体机评测 整体配置相当强大
JNI技术在嵌入式开发中的应用
【ModernCpp】新特性之CTAD代码示例
创建一种抗海水干扰的传感机制,实现海水污染物检测“抗干扰”
浅谈工业生产现场数字化现状与痛点
华为P10发布会前瞻:5大理由和亮点抢先看,价格曝光提前预约!华为P10你买得到吗?
深度解析Linux SPI总线和设备驱动架构
中兴通讯在数字经济时代的定位和使命
青岛12000辆出租车将安装全新智能终端
关于北京市新能源车换绿牌的相关问题
LED投光灯安装步骤及注意事项
基于海思5G模组中间件的5G模组RG801H
医学超声影像技术获得新发展
蔚来ET7搭载全球首款UWB数字钥匙
手机万能充电器电路原理与维修
Alexa说说你的人工智能是怎么来的
一款全球最小、性能最好的声学射频放大器