优先使用C++的别名声明(using)来替换typedef
C++98中,我们如果想用简写的方式表达一个类型,那么可以使用typedef关键字:
typedef std::unique_ptr<std::unordered_map<std::string, std::string>> UPtrMapSS;
C++11中,提供了别名声明的语法来取代typedef:
using UPtrMapSS = std::unique_ptr<std::unordered_map<std::string, std::string>>;
既然这两种语法都可以代表对一种类型的简写,那为什么一定要用using而不是typedef呢?
理由之一是,用using来声明函数指针时会更直观一些:
typedef void (function*) (int, int);
using function = void (*) (int, int);
直观与否,见仁见智,这其实不是一个非常必要的原因。using真正强大的地方在于它对模板的支持。
比方说我们要声明一个模板类型的简写,用using可以非常简单地实现:
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;
MyAllocList<Widget> lw;
如果要用typedef的话,就会变得非常麻烦了:
template<typename T>
struct MyAllocList{
typedef std::list<T, MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw;
除此之外,如果我们想在模板类中使用它,且MyAllocList的类型T是从模板形参指定的话,我们还要加上typename前缀:
template<typename T>
class Widget
{
private:
typename MyAllocList<T>::type l;
}
之所以要加typename是因为在这里编译器无法分辨MyAllocList::type究竟是MyAllocList里定义的类型还是一个成员变量,因此需要手动通过typename来标识一下。
如果使用的是using就完全不用关心这个问题,因为using本身就是在告诉编辑器这是一种类型。
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;
template<typename T>
class Widget
{
private:
MyAllocList<T> l;
}
因此在日常写代码中,还是应当尽量都转换到以using来声明类型的别名,而不再使用typedef。
优先使用C++的别名声明(using)来替换typedef的更多相关文章
- Item 9: 比起typedef更偏爱别名声明(alias declaration)
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 我确信我们都同意使用STL容器是一个好主意,并且我希望在Item ...
- Linux中命令别名alias与命令替换
当我们使用bash进行一些操作的时候,希望一些较为长的命令使用一些短的命令即可完成输入运行的话,我们就可以使用alias命令别名来帮助我们完成这个任务 alias作为一个bash的内置命令,具有一定的 ...
- Effective Modern C++:05右值引用、移动语义和完美转发
移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...
- Effective Modern C++:03转向现代C++
07:在创建对象时注意区分()和{} 自C++11以来,指定初始化值的的方式包括使用小括号,等号,以及大括号: ); // initializer is in parentheses ; // ini ...
- 【c++ Prime 学习笔记】第2章 变量和基本类型
2.1 基本内置类型 基本数据类型包含了算术类型(arithmetic type)和空类型(void) 算数类型,包含了字符.整型数.布尔值和浮点数 空类型,不对应具体的值 2.1.1 算术类型 算术 ...
- 【转】#define 定义别名和 typedef 声明类型的区别
下面一段程序的执行结果是: #include <stdio.h>#define CHAR2 char*int main(){ typedef char* CHAR; CHAR ...
- Swift声明参考
一条声明可以在你的程序里引入新的名字和构造.举例来说,你可以使用声明来引入函数和方法,变量和常量,或者来定义 新的命名好的枚举,结构,类和协议类型.你也可以使用一条声明来延长一个已经存在的命名好的类型 ...
- Item 13: 比起iterator优先使用const_iterator
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 STL中的const_iterator等价于pointers-to ...
- Swift5 语言参考(六) 声明
一个声明引入了一个新的名称或构建到你的程序.例如,您使用声明来引入函数和方法,引入变量和常量,以及定义枚举,结构,类和协议类型.您还可以使用声明来扩展现有命名类型的行为,并将符号导入到其他地方声明的程 ...
- Yii2的深入学习--别名(Aliases)
在之前自动加载机制的文章中,我们有提到别名,提到 getAlias 方法,大家当时可能不太清楚,这到底是什么,今天我们就来说一下别名. 别名用来表示文件路径和 URL,这样就避免了将一些文件路径.UR ...
随机推荐
- bilibili经典面试题
1. 如何向面试官解释什么是Redis,看看普通人和高手是如何回答的?_哔哩哔哩_bilibili 2.Java面试热点问题,synchronized原理剖析与优化_哔哩哔哩_bilibili 3.黑 ...
- windows环境下部署项目
有些时候,我们的项目不得不用windows服务器部署,但是需要注意的是,windows服务是无法开启多进程处理请求的. 本文介绍如何在windows上部署flask项目,应用 apache + mod ...
- elasticSearch(六)--全文搜索
数据案例 1.匹配查询 a.单词查询 执行match步骤: ·检查field类型:title字段为(analyzed)字符串,所以搜索时,title需要被分析. ·分析查询字符串:QUICK! 经过标 ...
- Python 面试题整理
一.语言特性 1.什么是Python?使用Python有什么好处?Python和其他语言的区别? Python是一种编程语言,它有对象,模块,线程,异常处理和自动内存管理. 好处:开源.简洁.简单.方 ...
- vvv,具名插槽
<!DOCTYPE html> <html> <head> <script src="a.js"></script> & ...
- centos7 系统初始化配置
1.设置ip地址 [root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens192 PROXY_METHOD="none ...
- viewpager加fragment可滑动加radio跟随滑动
public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, V ...
- .net基础—多线程(二)
Thread 在.NET中最早提供的控制线程类型的类型:System.Threading.Thread类.使用该类型可以直观地创建.控制和结束线程.下面是一个简单的多线程程序: static void ...
- Pr视频软件主要知识点
1,选中某一个面板,点击"Tab键上的 '波浪号' 键"即可将这个面板全屏展示 . 2,新建序列项目:自定义,25帧/s,方形像素,无场(逐行扫描). 3,序列面板素材自动缩放适 ...
- vuexy full-wersion项目安装报错问题处理
npm install grpc@1.23.3 --ignore-scripts npm rebuild node-sass