3.10 模板的别名

类别:部分人

在C++中,使用typedef为类型定义别名。比如:


typedef int myint;


就定义了一个int的别名myint。当遇到一些比较长的名字,尤其是在使用模板和域的时候,使用别名的优势会更加明显。比如:


typedef std::vector<std::string>strvec;


这里使用strvec作为std::vector<std::string>的别名。在C++11中,定义别名已经不再是typedef的专属能力,使用using同样也可以定义类型的别名,而且从语言能力上看,using丝毫不比typedef逊色。我们可以看看代码清单3-51所示的这个例子。

代码清单3-51


include <iostream>

include <type_traits>

using namespace std;

using uint=unsigned int;

typedef unsigned int UINT;

using sint=int;

int main(){

cout<<is_same<uint,UINT>::value<<endl;//1

}

//编译选项:g++ -std=c++11 3-10-1.cpp


在本例中,使用了C++11标准库中的is_same模板类来帮助我们判断两个类型是否一致。is_same模板类接受两个类型作为模板实例化时的参数,而其成员类型value则表示两个参数类型是否一样。在代码清单3-51所示的例子中我们看到,使用using uint=unsigned int;定义的类型别名uint和使用typedef unsigned int UINT;定义的类型别名UINT都是一样的类型。两者效果相同,或者说,在C++11中,using关键字的能力已经包括了typedef的部分。

在使用模板编程的时候,using的语法甚至比typedef更加灵活。比如下面这个例子:


template<typename T>using MapString=std::map<T,char*>;

MapString<int> numberedString;


在这里,我们“模板式”地使用了using关键字,将std::map<T,char*>定义为了一个MapString类型,之后我们还可以使用类型参数对MapString进行类型的实例化,而使用typedef将无法达到这样的效果。