- typedef不支持模板化、但别名声明支持
- 别名模板可以让人免写“::type”后缀,并且在模板内,对于内嵌typedef的引用经常需要加上typename前缀
在程序中,我们有时候需要用到很长的型别类型,例如:“std::unique_ptr<std::unordered_map<std::string,std::string>>”。这么长的类型,以往我们会使用typedef来定义别名。但是在C++11中,新增了别名声明来替代它。
//使用typedef:
typedef
std::unqiue_ptr<std::unordered_map<std::string,std::string>>
UPtrMapSS;
//使用别名声明:
using UPtrMapSS =
std::unqiue_ptr<std::unordered_map<std::string,std::string>>;
C++11引入的别名声明很好的替代了typedef,并拥有很多优点,最重要的一点就是模板中的应用。
别名声明可以模板化,typedef就不行。C++98时代我们必须要嵌套在模板化的struct里的typedef才能硬搞出来的东西,C++11可以直截了当的表达。比如我们想要定义一个链表的同义词,它使用了一个自定义的分配器MyAlloc:
//使用别名声明:MyAllocList<T>是std::list<T,MyAlloc<T>>同义词
template<typename T>
using MyAllocList = std::list<T,MyAlloc<T>>;
MyAllocList<Widget> lw;
//使用typedef:MyAllocList<T>::type是std::list<T,MyAlloc<T>>同义词
template<typename T>
struct MyAllocList
{
typedef std::list<T,MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw;
更坏的情况是,如果我们想要在模板内使用typedef来创建一个链表,它容纳的对象型别由模板形参指定的话,我们就要给typedef的名字加上一个typename前缀。因为MyAllocList<Widget>::type代表一个依赖于模板型别形参(T)的型别,所以MyAllocList<Widget>::type称为依赖型别,C++规定依赖型别前面必须要加上typename。但是当我们使用别名模板来定义,那么写typename的要求就消失了,连同::type
后缀也不需要了:
//typedef:
template<typename T>
struct MyAllocList
{
typedef std::list<T,MyAlloc<T>> type;
};
template<typename T>
class Widget
{
private:
typename MyAllocList<T>::type list;
};
//别名声明:
template<typename T>
using MyAllocList = std::list<T,MyAlloc<T>>;
template<typename T>
class Widget
{
private:
MyAllocList<T> list;
};