条款9:优先考虑别名声明 (using) 而非 typedef
基本用法对比
类型
语法
示例
typedef
旧写法(C++98)
typedef std::vector
using(别名声明)
新写法(C++11)
using VecInt = std::vector
两者功能一致,但 using 更简洁、可读性更高,推荐使用。
函数指针写法对比
// typedef 形式
typedef void (*FP)(int, const std::string&);
// using 形式(更清晰)
using FP = void (*)(int, const std::string&);
using 支持别名模板,typedef 不支持
C++11:别名模板写法更简洁
// 定义一个别名模板 MyAllocList,用于简化带有自定义分配器 MyAlloc 的 std::list 写法
// 对于任意类型 T,MyAllocList
template
using MyAllocList = std::list
// 创建一个名为 lw 的变量,它的类型是 MyAllocList
// 实际类型是 std::list
MyAllocList
C++98:typedef 只能通过嵌套 struct 实现
// 定义一个模板结构体 MyAllocList,接收一个类型参数 T
template
struct MyAllocList {
// 在结构体中定义一个类型别名 type,表示使用自定义分配器 MyAlloc 的 std::list
// 即 type 等价于 std::list
typedef std::list
};
// 使用 MyAllocList
// 由于我们用了 typedef,获取定义的类型要写成 "::type" 的形式,比较繁琐
MyAllocList
编译器对 typename 的要求不同
先看这个例子:
template
struct MyAllocList {
typedef std::list
};
现在在另一个模板中想用它:
template
class Widget {
MyAllocList
};
为什么报错?
因为 MyAllocList
这在 C++ 术语里叫 dependent name(依赖名字);
所以必须显式告诉编译器:这是一个类型,用 typename:
正确写法:
template
class Widget {
typename MyAllocList
};
再看对比:using 就不需要 typename
template
using MyAllocList = std::list
template
class Widget {
MyAllocList
};
C++14 的改进:提供统一的 _t 后缀别名
C++11 写法(繁琐):
typename std::remove_const
typename std::add_lvalue_reference
C++14 新写法:
std::remove_const_t
std::add_lvalue_reference_t
如果项目还在用 C++11,可以手动实现这些别名:
template
using remove_const_t = typename std::remove_const
总结
优先使用 using 声明别名,取代 typedef。
使用别名模板 (using) 可以让模板代码更简洁,省去 ::type 和 typename。
C++14 起应优先使用 _t 后缀形式的 type traits 别名(如 remove_const_t
避免在现代 C++ 中使用繁琐的 typedef 结构,特别是模板相关的。