《Effective Modern C++》学习笔记 - Item 9: 倾向于使用别名声明(alias declaration)而不是 typedef

  • alias declaration 和 typedef 做的事情完全相同,并且有充分理由使用前者替代后者。
  • 为了引入,作者开了个玩笑:如果你要用一个类型std::unique_ptr<std::unordered_map<std::string, std::string>>,你绝对不想把它写两次。想想都觉得要增加得腕管综合征(俗称:鼠标手)的风险。
  • C++11中 alias declaration 的语法为:
using UPtrMapSS =
	std::unique_ptr<std::unordered_map<std::string, std::string>>;
  • alias declaration 的主要优势在于模板。它可以被模板化而 typedef 不行。在C++98里如果要用 typedef 实现模板则需要用内嵌在结构体中的 hack 方法。例如,我们要定义使用一个自定义的空间分配器 MyAlloc<T> 的 STL 容器链表(list)的别名:
template<typename T>
class MyAlloc { // 自定义Alloc实现... }

// 使用alias declaration, 小菜一碟
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>;
MyAllocList<Widget> lw1;

// 使用typedef
template<typename T>
struct MyAllocList
{
	typedef std::list<T, MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw2;
  • 如果模板化的 typedef 的类型要在另一个模板中使用,情况会变得更糟。例如我们要在下面这个类中声明一个成员变量:
template<typename T>
class TemplatedClass {
public:
	// MyAllocList<T>::type list; // 错误!
	typename MyAllocList<T>::type list;
};
  • MyAllocList<T>::type 的类型取决于 T,是一个 dependent type,编译器没理由确信它就一定会是个类型名。C++规定这种情况下要用关键字 typename 来声明其的确是类型。于是,typedef 的解决方案相比 alias declaration 平白多出了两部分:typename::type
  • 作者提到C++11标准库中存在有关该条款的历史遗留问题。例如,在模板元编程时有时需要对类型 T 去除 const& 标识符。C++11提供的实现居然就是用上述 typedef + 结构体的hack方法,直到C++14才提供了 alias declaration 的版本,导致现在标准库中存在两份功能一样的方法(而且完全没有理由不用后者而用前者):
const int a = 0;
// 以remove_const为例, remove_reference, add_lvalue_reference等情况类似
std::remove_const<decltype(a)>::type 	b = a; 	// typedef方法
std::remove_const_t<decltype(a)> 		c = a;	// alias declaration方法,与上面语句效果完全相同

cout << type_id_with_cvr<decltype(a)>().pretty_name() << endl; 	// 输出const int
cout << type_id_with_cvr<decltype(b)>().pretty_name() << endl;	// 输出int
cout << (type_id_with_cvr<decltype(b)>() == type_id_with_cvr<decltype(c)>()) << endl; // 输出1
  • 实际上标准库中后者就是对前者的别名:
    在这里插入图片描述

总结

  1. typedef 不支持模板化,而 alias declaration 支持。
  2. alias declaration 方法避免了 typedef 通常要用的 typename 前缀和 ::type 后缀。
  3. C++14提供C++11中所有 type traits 变换的 alias declaration 版本。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值