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的更多相关文章

  1. Item 9: 比起typedef更偏爱别名声明(alias declaration)

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 我确信我们都同意使用STL容器是一个好主意,并且我希望在Item ...

  2. Linux中命令别名alias与命令替换

    当我们使用bash进行一些操作的时候,希望一些较为长的命令使用一些短的命令即可完成输入运行的话,我们就可以使用alias命令别名来帮助我们完成这个任务 alias作为一个bash的内置命令,具有一定的 ...

  3. Effective Modern C++:05右值引用、移动语义和完美转发

    移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...

  4. Effective Modern C++:03转向现代C++

    07:在创建对象时注意区分()和{} 自C++11以来,指定初始化值的的方式包括使用小括号,等号,以及大括号: ); // initializer is in parentheses ; // ini ...

  5. 【c++ Prime 学习笔记】第2章 变量和基本类型

    2.1 基本内置类型 基本数据类型包含了算术类型(arithmetic type)和空类型(void) 算数类型,包含了字符.整型数.布尔值和浮点数 空类型,不对应具体的值 2.1.1 算术类型 算术 ...

  6. 【转】#define 定义别名和 typedef 声明类型的区别

    下面一段程序的执行结果是: #include <stdio.h>#define CHAR2 char*int main(){    typedef char* CHAR;    CHAR ...

  7. Swift声明参考

    一条声明可以在你的程序里引入新的名字和构造.举例来说,你可以使用声明来引入函数和方法,变量和常量,或者来定义 新的命名好的枚举,结构,类和协议类型.你也可以使用一条声明来延长一个已经存在的命名好的类型 ...

  8. Item 13: 比起iterator优先使用const_iterator

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 STL中的const_iterator等价于pointers-to ...

  9. Swift5 语言参考(六) 声明

    一个声明引入了一个新的名称或构建到你的程序.例如,您使用声明来引入函数和方法,引入变量和常量,以及定义枚举,结构,类和协议类型.您还可以使用声明来扩展现有命名类型的行为,并将符号导入到其他地方声明的程 ...

  10. Yii2的深入学习--别名(Aliases)

    在之前自动加载机制的文章中,我们有提到别名,提到 getAlias 方法,大家当时可能不太清楚,这到底是什么,今天我们就来说一下别名. 别名用来表示文件路径和 URL,这样就避免了将一些文件路径.UR ...

随机推荐

  1. MySQL Delete 表数据后,磁盘空间并未释放,为什么?

    有开发小哥咨询了一个问题,记录一下处理过程分享给有需要的朋友.问题如下:MySQL数据库中有几张表增删比较频繁.数据变动剧烈且数据量大,导致数据增长过快,磁盘占用多.为了节约成本,定期进行数据备份,并 ...

  2. tomcat前后端项目部署及调优

    第1章 tomcat简介Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache,Sun和其他一些公司及个人共同 ...

  3. C# Linq查本集合中不包含于另一个集合的元素

    public void Linq() { List<Product> products = GetProductList(); List<Customer> customers ...

  4. 删除File Explorer、This PC、Folders

    win+R,输入regedit,打开Registry Editor 定位:Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentV ...

  5. 腾讯云服务器,在本地域名不能访问,IP可以访问;端口访问差异:有的地方能访问有的不能

    本地域名不能访问原因是DNS地址问题,本地设置的DNS地址没法解析出腾讯云IP,所以域名访问不到,直接就用服务器IP却可以. 修改DNS可以在本地电脑上修改,只影响本机, 按下键盘上的"Wi ...

  6. python获取报文参考代码

    # -*- coding:utf-8 -*- import sys import stomp import logging import time class MyListener(object): ...

  7. Sentinel 高可用流量管理框架

    出处:https://www.oschina.net/p/sentinel?hmsr=aladdin1e1 Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流.流量 ...

  8. BASE64编码作业

    BASE64编码作业 什么是BASE64编码 ase64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.可查看RFC2045-RF ...

  9. nmon 采坑

    1.安装 wget http://sourceforge.net/projects/nmon/files/nmon16g_x86.tar.gz 2.解压 tar -zxvf nmon16g_x86.t ...

  10. ANSYS Electronics Suite 19.2下载地址及其安装教程

    ANSYS Electronics Suite 19.2下载安装教程 1.下载地址https://getintopc.site/ansys-electronics-suite-19-2-free-do ...