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

  • 别名声明(alias declaration)和typedef做的事情完全相同,并且前者完全可以代替后者而存在
  • 对于函数别名而言using更加容易理解
typedef void (*FP)(int, const std::string&)
// using
using FP = void (*)(int, const std::string&)
  • 别名声明(alias declaration)更大的优势点在于在于模版,别名声明可以被模板化,但是typedef不能。考虑一个链表的别名,链表使用自定义的内存分配器,MyAlloc。使用别名模板,这真是太容易了:
template<typename T>
using MyAllocList = std::list<T, MyAlloc<T>>

MyAllocList<Widget> lw;

使用typedef,你就从头开始

template<typename T>
struct MyAllocList{
  typedef std::list<T, MyAlloc<T>> type;
};

MyAllocList<Widget>::type lw;
  • 如果模板化的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的版本,导致现在标准库中存在两份功能一样的方法(而且完全没有理由不用后者而用前者):
// remove_const 使用typedef
template<typename _Tp>
  struct remove_const<_Tp const> 
  { typedef _Tp     type; };
// 使用using
template<typename _Tp>
  using remove_const_t = typename remove_const<_Tp>::type;

参考

  1. item9-翻译
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值