C++11 新特性:模板别名

参考文章: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 最新版本的代码中看到这些别名的用例。

Leave a Reply