虽然使用 auto
可以大大简化代码,但对于一些使用 dynamic_cast
的结果不能用 auto
作为占位符。将冗长的变量类型简化仍然是很头疼的一个问题,幸好 C++11 提供了用关键字 using
给类型起别名的特性,既能有效简化代码,又不影响可读性。
#define 与 typedef
C 中就已经存在使用 #define
/ typedef
来给类型取别名的用法,但为什么还要多此一举用 using
?它们的区别在哪?
#define
是宏定义指令,其在预处理阶段直接将源码文本进行替换,不进行类型检查。
也就是说,如果
#define
为一个不存在的类型取了别名,写代码的时候 IDE 并不会给你飘红线,但编译时就会报一堆错误。
而对于 typedef
,其在编译时期执行,故可以进行类型检查,但它不能直接进行模板替换,只能采用外面套一个结构体的方式。也就是说,如果定义了这样一个类模板:
template<typename T>
class A {};
如果试图用 typedef
取模板别名,则必须用上面那种写法,下面那种写法会报错:
// OK
template<typename T>
struct Alias {
typedef A<T> a_t;
};
// ERROR
template<typename T>
typedef A<T> a_t;
这样起别名的方式又增加了冗余的结构体名,降低了可读性与 code 效率。
不仅如此,typedef
在定义函数指针时也存在降低可读性的情况:
typedef void (*func) (int, int); // func 为函数指针 void(*)(int, int) 的别名
在网上找到很多说
typedef
/#define
无法起模板别名的文章,但实际操作了一遍,发现或许是编译器更新了,一些以前认为无法实现的代码如今都能编译通过。所以还是绝知此事要躬行。
using
using
不仅可以用于导入命名空间或类成员,还可以用于起别名。事实上,using
能够实现的功能也已经完全将 typedef
能做的包含在内,完全可以舍弃功能单一并且代码反人类直觉的 typedef
,改用可读性更高的 using
。
委员会既然推出了这一新特性,照着用就完事了~
关于 using
的用法,简单来说就是这样的:
using new_alias = old_typename;
// or
template<typename T>
using new_alias = old_typename<T>;
如果需要使用 using
为函数指针取别名,则可以直接用类似赋值的方式,即
using func = void(*)(int, int);
一目了然,符合直觉。