将部分专用模板作为模板参数传递

aka*_*ihi 4 c++ templates metaprogramming

我有一个类模板,期望一些其他模板作为参数:

template<
    class Key, 
    template <typename K,template <typename T> class Allocator> class Policy
>
class container {
     Policy<Key,Allocator>* _policy;
     //some code here
};
Run Code Online (Sandbox Code Playgroud)

通常我将它与策略类一起使用,如下所示:

template <class Key,template <typename T> class Allocator> class policy {
    //some code
};
Run Code Online (Sandbox Code Playgroud)

但是如果我必须将额外的模板参数传递给策略类呢?就像是:

template <time_t Age,class Key,template <typename T> class Allocator> class policy_3 {
    //some code
};
Run Code Online (Sandbox Code Playgroud)

我该怎么办,允许该类用户通过Age paratemeter而不接触其他人?例如:

typedef container<key_type,policy_3<100500> > containerWithAge;
Run Code Online (Sandbox Code Playgroud)

Mar*_*utz 8

您有两个选择:绑定和重新绑定.

在绑定中,您可以将三元策略调整为二进制策略,正如template-template参数所期望的那样Policy:

template <typename Key, template <typename T> class Allocator>
struct policy_3_100500 : ternary_policy<100500,Key,Allocator> {};
Run Code Online (Sandbox Code Playgroud)

并使用policy_3_100500而不是policy_3<100500>.

为了更接近您正在拍摄的语法,您可以使用嵌套类:

template <time_t Age>
struct policy_3 {
    template <typename Key, template <typename T> class Allocator>
    struct type : ternary_policy<Age,Key,Allocator> {};
};
Run Code Online (Sandbox Code Playgroud)

并使用policy_3<100500>::type而不是policy_3<100500>.

获得所需语法的唯一方法是使用策略将其::type 移入类中.这是第二个选项:重新绑定(这也用于std :: allocator,btw).在这种情况下,您将传递Policy作为普通模板参数,并假设模板元函数,例如bind,存在:

template <time_t Age>
struct policy_3 {
    template <typename Key, template <typename T> class Allocator>
    struct bind : ternary_policy<Age,Key,Allocator> {};
};
Run Code Online (Sandbox Code Playgroud)

虽然结构上与第二个选项相同,但区别在于谁调用 bind:在第一个选项(绑定)中,它是策略类的用户(通过policy<100500>::type显式传递).在这里,它是使用该策略的类:

template <typename Key, typename Policy>
struct container {
    typename Policy::template bind<Key,std::allocator<Key>> * _policy;
    // ...
}:
Run Code Online (Sandbox Code Playgroud)

总的来说,Policy类通常不作为模板模板参数传递,而是作为普通的模板参数传递(正是因为它们本身可能有不同数量的参数).然后,使用策略的类假定在策略中存在某个内部结构(typedef,函数,元函数,常量),这bind只是一个示例.