C++11 模板元编程 - template template parameter

106 阅读1分钟
#include <algorithm>
#include <deque>
#include <vector>
#include <iostream>
using namespace std;
template <template <typename T, typename Allocator = std::allocator<T> > class Out_container,
          template <typename T, typename Allocator = std::allocator<T> > class In_container,
          typename T>
Out_container<T> resequence(const In_container<T> &in_container)
{
    Out_container<T> out_container;
    for (auto x : in_container)
    {
        out_container.push_back(x);
    }
    return out_container;
}

int main()
{
    vector<int> v{1, 2, 3, 4, 5};
    // deque<int> d = resequence<deque<int>, vector<int>, int>(v);
    auto d = resequence<deque, vector, int>(v);
    // auto d = resequence<deque>(v); //编译器可以推断出来其他两个模板参数
    for (auto& elem : d) {
        cout << elem << " ";
    }
    return 0;
}

C++模版元编程中有一个概念叫 template template parameter, a template parameter is itself a template, 即模板参数本身也是一个模板。

如上所示,我们希望定义一个resequence 函数,接受三个模版参数,<Out_container, In_container, T>, 将一种容器转换为另一种容器,需要注意的是在写模版函数的时候,STL中常见的容器类模板在stl库中的定义有两个类型参数,第一个参数是元素类型,第二个参数是分配器allocator的类型。虽然一般容器的的第二个类型参数有默认值,但是当编译器使用STL中容器替换Container时却会严格匹配参数,默认值被忽略了。 因此,对于上述模版函数中的容器,我们需要定义其默认的第二个模版参数,即Allocator.

如果不定义默认的模板参数,则会出现报错