一、typedef 关键字
1. 基本语法
typedef ExistingType AliasName;
- ExistingType 是现有的类型。
- AliasName 是新定义的类型别名。
示例:
typedef int Integer; // Integer 是 int 的别名
Integer x = 10; // 等价于 int x = 10;
2. 使用场景和优点
- 简化复杂类型的书写。
- 增强代码的可读性。
示例:简化复杂类型
typedef unsigned long long ULL; // ULL 是 unsigned long long 的别名
ULL largeNumber = 1234567890123456789;
示例:函数指针
函数指针的定义比较复杂,使用 typedef 可简化书写。
typedef int (*FunctionPointer)(int, int); // 定义一个函数指针类型别名
int add(int a, int b) {
return a + b;
}
FunctionPointer fp = add; // 使用别名定义函数指针变量
3. typedef 的局限性
- 不能定义模板类型别名:对于模板类型,typedef 显得无能为力。例如,要为模板类型定义别名:
template <typename T>
typedef T* Ptr; // 错误,编译失败
二、using 声明(C++11 引入)
1. 基本语法
using AliasName = ExistingType;
- 语法更加直观,将别名的定义与类型关联起来。
示例:
using Integer = int; // Integer 是 int 的别名
Integer x = 10; // 等价于 int x = 10;
. using 的强大功能
(1)支持模板类型别名
using 不仅可以为普通类型定义别名,还可以为模板类型定义别名。
template <typename T>
using Ptr = T*; // 定义模板类型别名
Ptr<int> p = nullptr; // 等价于 int* p = nullptr;
Ptr<double> dp = nullptr; // 等价于 double* dp = nullptr;
示例:简化模板类型
template <typename T>
using Vector = std::vector<T>; // Vector 是 std::vector<T> 的别名
Vector<int> v; // 等价于 std::vector<int> v;
(2)简化复杂的类型
using StringList = std::vector<std::string>;
StringList names = {"Alice", "Bob", "Charlie"};
(3)结合函数指针
using FunctionPointer = int (*)(int, int); // 定义函数指针类型别名
int multiply(int a, int b) {
return a * b;
}
FunctionPointer fp = multiply; // 使用函数指针别名
三、typedef 和 using 的区别
四、实践对比
示例 1:为函数指针定义别名
typedef void (*Callback)(int, int); // 使用 typedef
using Callback = void (*)(int, int); // 使用 using
两者功能等价,但 using 更加简洁。
示例 2:模板类型别名
template <typename T>
using Map = std::map<std::string, T>; // 仅 using 支持模板类型别名
Map<int> m; // 等价于 std::map<std::string, int>
对于模板,using 是唯一选择。
五、推荐使用场景
- 普通类型别名:typedef 和 using 都可以,推荐使用 using,语法更直观。
- 模板类型别名:必须使用 using,因为 typedef 不支持模板。
- 复杂类型:using 提供了更简洁的语法,优于 typedef。
总结
类型别名的选择建议
- 普通类型别名:
- 推荐使用 using,因为语法更直观。
- 例如:using Integer = int;
- 模板类型别名:
- 必须使用 using,因为 typedef 不支持模板类型。
- 例如:template <typename T> using Ptr = T*;
- 简化复杂类型:
- 使用 using 定义嵌套类型别名,提高代码可读性。
- 例如:using MapType = std::map<std::string, std::vector<int>>;