参考文章:https://blogs.oracle.com/pcarlini/entry/template_aliases
2002 年,ISO C++ 标准化组织就已经提出了模板别名的概念。不过那时候还是叫做 typedef template。在接下来的几年中,以 Gabriel Dos Reis 和 Bjarne Stroustrup 为代表的开发者发展了这个想法,最终,我们在 C++ 11 中见到了这个新特性—— template aliases。
不过,只有在最新版本的 GCC 实现中才能使用这个特性(4.7 或更新版本)。但这并不是说这个特性很难实现——其实它是很容易实现的,对容器和内存管理函数这样的库尤其有用。可能只是开发者忘记在之前的版本中添加上这个功能 ;-P。
这个特性的核心功能很简单:提供类型族的别名。注意,这里并没有引入新的关键字,而是使用旧的using
关键字,加上新的语法组成。例如:
#include <vector> template<class T> struct Alloc { /* ... */ }; template<class T> using Vec = std::vector<T, Alloc<T>>; Vec<int> v; // 等价于 std::vector<int, Alloc<int>> v;
我们为所有可能的 T 类型的std::vector<T, Alloc<T>>
声明了一个名字 Vec。这样,这个模板的别名就可以用作其它类型,只要直接加上 T 的实际类型就可以了。
我们可以写出更复杂的示例,但是语法还是一样的。把复杂的代码变得简单总是看起来很有趣的(对此而言,旧版本的 C++ 也有一些简化的写法)。如果对此感兴趣,那么就看看下面的代码吧:
template<typename T> class allocator { //... template<typename U> struct rebind { typedef allocator<U> other; }; }; allocator<T>::rebind<U>::other x;
我们用 C++ 11 的模板别名重写一下:
template<typename T> class allocator { //... template<typename U> using rebind = allocator<U>; }; allocator<T>::rebind<U> x;
事实上,在 C++ 11 的内存分配库、智能指针库以及其它各种库中,有很多类似 rebind 这样的模板别名。我们可以从 GCC 最新版本的代码中看到这些别名的用例。