优先使用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 ...
随机推荐
- Characterizing possible failure modes in physics-informed neural network
NeurIPS 2021 表征PINN中可能的失败模式.本文的思路也比较简单,通过对PINN的优化域进行观察,发现导致PINN训练的原因并不是因为神经网络的表达力不足,而是由于PINN中引入了基于PD ...
- 关于pytorch一些基础知识的备份
压缩conda环境用于备份目的实际上没有意义,因为还有其他方法可以做到这一点,这可能更合适,并使用专为此而设计的内置功能. 您可以创建一个环境.txt版本conda,详细说明其中的每个模块和版本,然后 ...
- fftw安装
1. 下载fftw 2.tar -zxvf fftw.tar.gz 3. ./configure --prefix=path --enable-sse2 --enable-avx --enable-f ...
- Vue的hash/history模式
hash路由模式 URL 中的 hash 值只是客户端的一种状态,向服务端发送请求的时候,hash 部分不会被发送: hash 值得改变会在浏览器的历史记增加访问记录,所以可以通过浏览器的回退.前进控 ...
- php基础教程(三)
PHP语法概述 A. 基本语法 即使初次接触PHP的用户也会发现自己对PHP的语法风格并不陌生. 例如:<?php echo "Hello!": ?> 显示结果为&qu ...
- new关键字解析
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例.new 关键字会进行如下的操作: 创建一个空的简单JavaScript对象(即{}): 链接该对象(即设置该对象的构造函数 ...
- 2022-3-15内部群每日三题-清辉PMP
1.一家公司被一家大公司收购,这家大公司希望把重点放在其核心产品和服务上.处于规划阶段的所有项目都正在进行修定,以包含新的变更管理程序.一个项目的项目经理需要持续的高级输入,以确保与新的组织结构保持一 ...
- 使用logback需要导入的jar包
jar包名 logback-access-1.1.2.jar logback-classic-1.1.2.jar logback-core-1.1.2.jar slf4j-api-1.7.25.jar ...
- 问题:配置apache的相关配置文件报错:Invalid command 'Order' (已解决)
1. 问题描述 在虚拟文件httpd-vhosts.conf里面,directory里加入Order allow,deny,重启apache,出现Invalid command 'Order', pe ...
- Peer Review
What are Peng (Bob) Chi's top 3 strengths? Can you give an example of how one or two of those stren ...