C++/C++11中用于定义类型别名的两种方法:typedef和using
类型别名(type alias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。在C++中,任何有效类型都可以有别名。
有两种方法可用于定义类型别名:传统的方法是使用关键字typedef;C++11中规定了一种新的方法,使用别名声明(alias declaration)来定义类型的别名,即使用using.
关键字typedef作为声明语句中的基本数据类型的一部分出现。含有typedef的声明语句定义的不再是变量而是类型别名。和以前的声明语句一样,这里的声明符也可以包含类型修饰,从而也能由基本数据类型构造出复合类型来。
C++11中用关键字using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成等号右侧类型的别名。
类型别名和类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名。
如果某个类型别名指代的是复合类型或常量,那么把它用到声明语句里就会产生意想不到的后果。
使用typedef定义的别名和使用using定义的别名在语义上是等效的。 唯一的区别是typedef在模板中有一定的局限性,而using没有。
尽管typedef具有更长的历史记录并且在现有代码中可能更常见,但using更通用。
无论是typedef还是using,它们都不会创建新的数据类型,它们仅仅创建现有类型的同义词(synonyms)。不能用于更改现有类型名称的含义。
typedef和using标识符可以声明数组和函数类型,指针和引用,类类型等等。但不能与任何其它标识符组合使用。仅在它们可见的范围内有效:不同的函数或类声明可以定义具有不同含义的相同名字的类型。
typedef的用法包括:定义一种类型的别名;用于struct声明;用来定义与平台无关的类型;用于回调函数;为复杂的声明定义一个新的简单的别名。
typedef是定义了一种类型的新别名,不同于宏,并不是简单的字符串替换。当const和typedef一起出现时,typedef不是简单的字符串替换:
注意:typedef int* INT; const INT p;相当于int* const p;而不是const int* p;
在使用typedef时,不能在声明中有多个存储类关键字:ypedef就像auto,extern, mutable, static, register一样,是一个存储类关键字。即typedef中不能出现这些关键字。
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
typedef.cpp内容如下:
#include "typedef.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <ios>
#include <type_traits>
#include <typeinfo>namespace typedef_ {///
// reference: https://en.cppreference.com/w/cpp/language/typedef// std::add_const, like many other metafunctions, use member typedefs
template< class T>
struct add_const {typedef const T type;
};int test_typedef_1()
{// simple typedeftypedef unsigned long ulong;// the following two objects have the same typeunsigned long l1;ulong l2;// more complicated typedeftypedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];// the following two objects have the same typeint a1[10];arr_t a2;for (int i = 0; i < 10; ++i)a2[i] = i;for (int i = 0; i < 10; ++i)fprintf(stdout, "a2 value: %d\n", a2[i]);// common C idiom to avoid having to write "struct S"typedef struct {int a; int b;} S, *pS;// the following two objects have the same typepS ps1;S* ps2;// error: storage-class-specifier cannot appear in a typedef declaration// typedef static unsigned int uint;// typedef can be used anywhere in the decl-specifier-seqlong unsigned typedef int long ullong;// more conventionally spelled "typedef unsigned long long int ullong;"// std::add_const, like many other metafunctions, use member typedefs/*template< class T>struct add_const { // error: a template declaration cannot appear at block scopetypedef const T type;};*/typedef struct Node {//struct listNode* next; // declares a new (incomplete) struct type named listNode} listNode; // error: conflicts with the previously declared struct namestruct Node2 {int data;struct Node2* nextptr;};// 使用typedef可以将上面的Node2改写为:typedef struct Node3 Node3;struct Node3 {int data;Node3* nextptr;};typedef double wages; // wages是double的同义词typedef wages base, *p; // base是double的同义词,p是double*的同义词return 0;
}// reference: http://www.cplusplus.com/doc/tutorial/other_data_types/
int test_typedef_2()
{// In C++, there are two syntaxes for creating such type aliases:// The first, inherited from the C language, uses the typedef keyword:// typedef existing_type new_type_name;
{ typedef char C;typedef unsigned int WORD;typedef char * pChar;typedef char field [50];C mychar, anotherchar, *ptc1;WORD myword;pChar ptc2;field name;
}// a second syntax to define type aliases was introduced in the C++ language:// using new_type_name = existing_type;
{//the same type aliases as above could be defined as:using C = char;using WORD = unsigned int;using pChar = char *;using field = char [50];
}{// 注意: typedef int* INT; const INT p;相当于int* const p;而不是const int* p;typedef int* INT;int a[] = {1, 2, 3};const INT p1 = &a[0];const int* p2 = &a[0];//++p1; // error: increment of read-only variable 'p1'p1[0] = -100;fprintf(stdout, "a[0]: %d\n", a[0]);++p2;//p2[0] = -200; // error: assignment of read-only location '*p2'
}return 0;
}// reference: https://msdn.microsoft.com/en-us/library/dn467695.aspx
void actual_function(int arg) { fprintf(stdout, "value: %d\n", arg); }
template<typename T>
using ptr2 = T*;template<typename T>
struct MyAlloc {typedef T value_type;MyAlloc() { }template<typename U>MyAlloc(const MyAlloc<U>&) { }bool operator == (const MyAlloc&) const { return true; }bool operator != (const MyAlloc&) const { return false; }T* allocate(const size_t n) const {fprintf(stdout, "start allocate\n");if (n == 0) {return nullptr;}if (n > static_cast<size_t>(-1) / sizeof(T)) {throw std::bad_array_new_length();}void* const pv = malloc(n * sizeof(T));if (!pv) {throw std::bad_alloc();}return static_cast<T*>(pv); }void deallocate(T* const p, size_t) const {fprintf(stdout, "start deallocate\n");free(p);}
};using MyIntVector = std::vector<int, MyAlloc<int>>;int test_typedef_3()
{{ // An alias does not introduce a new type and cannot change the meaning of an existing type name// C++11 using counter = long; // C++03 equivalent: // typedef long counter;
}{ // Aliases also work with function pointers// C++11 using func = void(*)(int); // C++03 equivalent: // typedef void (*func)(int); // func can be assigned to a function pointer value func fptr = &actual_function;fptr(10);
}{ // A limitation of the typedef mechanism is that it doesn't work with templates. However, the type alias syntax in C++11 enables the creation of alias templates://template<typename T> using ptr = T*; // error: a template declaration cannot appear at block scope // the name 'ptr<T>' is now an alias for pointer to T ptr2<int> ptr_int;
}{ // an alias template with a custom allocatorMyIntVector foov = { 1701, 1764, 1664 };for (auto a: foov)fprintf(stdout, " %d ", a);fprintf(stdout, "\n");
}return 0;
}///
// reference: https://zh.wikipedia.org/zh-hk/Typedef
int do_math(float arg1, int arg2) { return arg2; }int call_a_func(int (*call_this)(float, int))
{int output = call_this(5.5, 7);return output;
}// 将上面改为使用typedef,回调函数
typedef int (*MathFunc)(float, int);
int call_a_func2(MathFunc call_this)
{int output = call_this(5.5, 7);return output;
}int test_typedef_4()
{int final_result = call_a_func(&do_math);fprintf(stdout, "final_result: %d\n", final_result);int final_result2 = call_a_func2(&do_math);fprintf(stdout, "final_result2: %d\n", final_result2);return 0;
}// reference: https://en.cppreference.com/w/cpp/language/type_alias
// type alias, identical to
// typedef std::ios_base::fmtflags flags;
using flags = std::ios_base::fmtflags;
// the name 'flags' now denotes a type:
flags fl = std::ios_base::dec;// type alias, identical to
// typedef void (*func)(int, int);
using func = void (*) (int, int);
// the name 'func' now denotes a pointer to function:
void example(int, int) {}
func f = example;// alias template
template<class T>
using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> x;// type alias used to hide a template parameter
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
mystring<char> str;// type alias can introduce a member typedef name
template<typename T>
struct Container { using value_type = T; };
// which can be used in generic programming
template<typename Container>
void g(const Container& c)
{typename Container::value_type n;fprintf(stdout, "type: %s\n", typeid(n).name());
}// type alias used to simplify the syntax of std::enable_if
template<typename T>
using Invoke = typename T::type;
template<typename Condition>
using EnableIf = Invoke<std::enable_if<Condition::value>>;
template<typename T, typename = EnableIf<std::is_polymorphic<T>>>
int fpoly_only(T t) { return 1; }struct S { virtual ~S() {} };int test_typedef_5()
{Container<int> c;g(c); // Container::value_type will be int in this function//fpoly_only(c); // error: enable_if prohibits thisS s;fpoly_only(s); // okay: enable_if allows thisreturn 0;
}} // namespace typedef_
CMakeLists.txt内容如下:
PROJECT(CppBaseTest)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)# 支持C++11
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2 -std=c++11")
# 支持C++14, when gcc version > 5.1, use -std=c++14 instead of c++1y
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2 -std=c++1y")MESSAGE(STATUS "project source dir: ${PROJECT_SOURCE_DIR}")
SET(PATH_SRC_FILES ${PROJECT_SOURCE_DIR}/./../../demo/CppBaseTest)
MESSAGE(STATUS "path src files: ${PATH_SRC_FILES}")# 指定头文件的搜索路径
INCLUDE_DIRECTORIES(${PATH_SRC_FILES})# 递归查询所有匹配的文件:*.cpp
FILE(GLOB_RECURSE CPP_LIST ${PATH_SRC_FILES}/*.cpp)
FILE(GLOB_RECURSE C_LIST ${PATH_SRC_FILES}/*.c)
#MESSAGE(STATUS "cpp list: ${C_LIST}")# 编译可执行程序
ADD_EXECUTABLE(CppBaseTest ${CPP_LIST} ${C_LIST})
# 用来为target添加需要链接的共享库,指定工程所用的依赖库,包括动态库和静态库
TARGET_LINK_LIBRARIES(CppBaseTest pthread)
build.sh脚本内容如下:
#! /bin/bashreal_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
cmake ..
makecd -
编译及测试方法如下:首先执行build.sh,然后再执行./build/CppBaseTest即可。
GitHub: https://github.com/fengbingchun/Messy_Test
相关文章:
iOS学习笔记--01swift实现提示框第三方库:MBProgressHUD
本文使用swift语言使用MBProgressHUD。 开源项目MBProgressHUD可以实现多种形式的提示框。使用简单,方便。GitHud的下载地址是:https://github.com/jdg/MBProgressHUD/ 下载完成后,将MBProgressHUD.h和MBProgressHUD.m拖入已经新建好的Swift项…

2019北京智源大会在京开幕, 中外学术大咖共话人工智能研究前沿
10月31日,由北京智源人工智能研究院主办的2019北京智源大会在国家会议中心开幕,会期两天。智源大会是北京创建全球人工智能学术和创新最优生态的标志性学术活动,定位于“内行的AI盛会”,以国际性、权威性、专业性和前瞻性为特色&a…

linux中登录类型及配置文件
linux中登录shell的类型1.交互式登录:直接通过终端输入用户信息登录1)login:2)在shell中 su - usernamesu -l username2.非交互式登录1)su username2)图形界面的终端3)执行脚本的过程用户配置文…

Swift项目引入第三方库的方法
分类:iOS(55) 目录(?)[] Swift项目引入第三方库的方法 转自 http://blog.shiqichan.com/How-To-Import-3rd-Lib-Into-Swift-Project/ 以下,将创建一个Swift项目,然后引入3个库: Snappy 简化autolayout代码…

最新NLP架构的直观解释:多任务学习– ERNIE 2.0(附链接)| CSDN博文精选
作者 | Michael Ye翻译 | 陈雨琳,校对 | 吴金笛来源 | 数据派THU(ID:DatapiTHU)百度于今年早些时候发布了其最新的NLP架构ERNIE 2.0,在GLUE基准测试中的所有任务上得分均远高于XLNet和BERT。NLP的这一重大突破利用了一…

C++中的内存对齐介绍
网上有很多介绍字节对齐或数据对齐或内存对齐的文章,虽然名字不一样,但是介绍的内容大致都是相同的。这里以内存对齐相称。注:以下内容主要来自网络。 内存对齐,通常也称为数据对齐,是计算机对数据类型合法地址做出了…

__cplusplus的用处
经常在/usr/include目录下看到这种字句: #ifdef __cplusplus extern "C" { #endif ... #ifdef __cplusplus } #endif 不太明白是怎么用的。今天阅读autobook,在第53页看到了作者的解释:C/C编译器对函数和变量名的命名方法不一样…

Linux下的内存对齐函数
在Linux下内存对齐的函数包括posix_memalign, aligned_alloc, memalign, valloc, pvalloc,其各个函数的声明如下: int posix_memalign(void **memptr, size_t alignment, size_t size); void *memalign(size_t alignment, size_t size); void *aligned_…

Swift2.0系列]Error Handling(项目应用篇)
1.FileManager中的应用 倘若你只是想看FileManager中的 Error Handling是如何实现的,请找到3.删除文件以及4.获取文件信息。我分别为你提供了do-catch以及try?的使用方法。 打开Xcode,选中Single View Application,输入项目名称例如FileManagerDemo,点击…

总点第一个视频产生选择偏差?Youtube用“浅塔”来纠正
作者 | Tim Elfrink译者 | Tianyu出品 | AI科技大本营(ID:rgznai100)【导读】本文来自于谷歌研究人员最近发表的一篇论文,介绍了视频平台 Youtube 的视频推荐方法,并在 RecSys 2019 大会上做了分享。本文总结归纳了一些论文中的重…

HTML样式offset[Direction] 和 style.[direction]的区别
为什么80%的码农都做不了架构师?>>> 以offsetLeft与style.left为例: offsetLeft使用的值是字符串,如“100px", style.left则使用数值,如 100 offsetLeft只可以读,因此用无法通过Js改变这个值实现样…
Ubuntu 14.04上安装pip3/numpy/matplotlib/scipy操作步骤
Ubuntu 14.04 64位上默认安装了两个版本的python,一个是python2.7.6,另外一个是python3.4.0,如下图所示: 安装完pip3的结果如下图所示: 升级完pip3的结果如下图所示: 安装完numpy的结果如下图所示: 通过sudo pip3 install matplot…

NSHelper.showAlertTitle的两种用法 swift
var model : CarCity CarCity() if (NSString.isNullOrEmpty(locationLabel.text)) { NSHelper.showAlertTitle(nil, message: "暂无法定位,请检查网络。", cancel: "确定") return } if (NSString.isNullOrEmpty(plateTextFild.text)) { NSHe…

通俗易懂:图卷积神经网络入门详解
作者 | 蝈蝈来源 | 转载自知乎用户蝈蝈【导读】GCN问世已经有几年了(2016年就诞生了),但是这两年尤为火爆。本人愚钝,一直没能搞懂这个GCN为何物,最开始是看清华写的一篇三四十页的综述,读了几页就没读了&a…

Java数据结构一 —— Java Collections API中的表
1.Collection接口 位于java.util包中,以下是重要的部分。 1 public interface Collection<AnyType> extends Iterable<AnyType> 2 { 3 int size(); 4 boolean isEmpty(); 5 void clear(); 6 boolean add(AnyType x); 7 …

Swift 中的内存管理详解
这篇文章是在阅读《The Swift Programming Language》Automatic Reference Counting(ARC,自动引用计数)一章时做的一些笔记,同时参考了其他的一些资料。 在早期的 iOS 开发中,内存管理是由开发者手动来完成的。因为传统…
Ubuntu14.04 64位机上配置OpenCV3.4.2+OpenCV_Contrib3.4.2+Python3.4.3操作步骤
Ubuntu 14.04 64位上默认安装了两个版本的python,一个是python2.7.6,另外一个是python3.4.3。这里使用OpenCV最新的稳定版本3.4.2在Ubuntu上安装python3.4.3支持OpenCV的操作步骤如下: 1. 更新包,执行: sudo apt-get update sud…

“Python之父”从Dropbox退休
作者 | 若名出品 | AI科技大本营(ID:rgznai100)10 月 30 日,Python 之父 Guido Van Rossum 宣布将从工作六年的 Dropbox 公司退休,他在 Twitter 上转发了 Dropbox 团队写的《Thank you, Guido》公开信长文。Guido 表示,…

谭浩强《C++程序设计》书后习题 第十三章-第十四章
2019独角兽企业重金招聘Python工程师标准>>> 最近要复习一下C和C的基础知识,于是计划把之前学过的谭浩强的《C程序设计》和《C程序设计》习题重新做一遍。 编译环境为:操作系统32位Win7,编译工具VC6.0 第十三章:输入输…
图像处理库(fbc_cv):源自OpenCV代码提取
在实际项目中会经常用到一些基本的图像处理操作,而且经常拿OpenCV进行结果对比,因此这里从OpenCV中提取了一些代码组织成fbc_cv库。项目fbc_cv所有的代码已放到GitHub中,地址为 https://github.com/fengbingchun/OpenCV_Test ,它…

Swift2.x编写NavigationController动态缩放titleView
这两天看到一篇文章iOS 关于navigationBar的一些..中的动态缩放比较有意思,看了一下源码,然后用Swift写了一下,使用storyboard实现. 效果图: 部分代码: 设置滑动代理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26/**设置滑动代理- parameter scrollV…

云厂商和开源厂商“鹬蚌相争”,他却看到了开发者的新机会
作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】过去一年,开发者生态发生了一些或巨大、或微妙的变化,大的变化如巨头云厂商正在通过开源、收购等方式争夺开发者生态,比如微软以 75 亿美金收购 GitHubÿ…

Error: could not open 'D:\Program Files\Java\jre7\lib\amd64\jvm.cfg'
重装JDK后,因为没有装在以前的目录,运行java命令后报错,环境变量的设置都没有问题。解决方法:删除c:/windows/system32/目录下的java.exe 、javaw.exe、javaws.exe,找不到的话在C:\Windows\SysWOW64下找。删除三个文件…
循环神经网络(RNN)简介
人工神经网络介绍参考: https://blog.csdn.net/fengbingchun/article/details/50274471 卷积神经网络介绍参考: https://blog.csdn.net/fengbingchun/article/details/50529500 这里在以上两篇基础上整理介绍循环神经网络: 前馈网络可以…

Swift 中 10 个震惊小伙伴的单行代码
几年前,函数式编程的复兴正值巅峰,一篇介绍 Scala 中 10 个单行函数式代码的博文在网上走红。很快地,一系列使用其他语言实现这些单行代码的文章也随之出现,比如 Haskell,Ruby,Groovy,Clojure&a…

满12万送Mate 30 Pro?华为云“双十一”20+款明星产品齐上线
双十一这次是真的真的真真真来了,华为云11.11血拼风暴一促即发!想好怎么玩转双十一了嘛?怎么买到低价高性价比的云主机?怎么抽到100%中奖的礼品?怎么当欧皇被免单?不仅红包、折扣、特惠、满赠、抽奖一样都没…

javascript json对象转字符串形式
2019独角兽企业重金招聘Python工程师标准>>> /*** json对象转字符串形式*/function json2str(o) {var arr [];var fmt function(s) {if (typeof s object && s ! null) return json2str(s);return /^(string|number)$/.test(typeof s) ? "" …

使用 NSURLSession 开发一个支持后台下载和断点续传的下载工具
NSURLSession 是 iOS 系统提供给我们的原生网络操作库,它提供了网络操作相关的一系列特性支持,比如缓存控制,Cookie管理,HTTP 认证处理等等,是一套整体的网络操作处理解决方案。 关于 NSURLSession 的基本特性…
SSHDroid及sshpass简介
一、SSHDroid简介 SSH为Secure Shell的缩写,是建立在应用层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH客户端适用于多种平台,几乎所有…

漫画:我用深度学习框架画下女朋友最美的脸
这不,又一个程序员为爱变身灵魂画手,看得我都想学画画了。阿华是幸运的,因为他找到了对的方法,事半功倍,最终有情人终成眷属。这也得益于 PyTorch 的易学易用,大多数人第一次使用 PyTorch 几乎可以做到无痛…