【问题标题】:Passing partially specialized template as a template parameter将部分专用模板作为模板参数传递
【发布时间】:2011-04-26 06:58:23
【问题描述】:

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

template<
    class Key, 
    template <typename K,template <typename T> class Allocator> class Policy
>
class container {
     Policy<Key,Allocator>* _policy;
     //some code here
};

通常我将它与这样的策略类一起使用:

template <class Key,template <typename T> class Allocator> class policy {
    //some code
};

但是如果我必须将额外的模板参数传递给策略类怎么办?比如:

template <time_t Age,class Key,template <typename T> class Allocator> class policy_3 {
    //some code
};

我该怎么做才能让该类的用户在不接触其他人的情况下通过年龄参数?例如:

typedef container<key_type,policy_3<100500> > containerWithAge;

【问题讨论】:

  • 将模板更改为简单的template&lt;class Key, class Policy&gt; 不是我认为的选项? :P

标签: c++ templates metaprogramming


【解决方案1】:

您有两种选择:绑定和重新绑定。

在绑定中,您将三元策略调整为二元策略,正如模板模板参数Policy 所期望的那样:

template <typename Key, template <typename T> class Allocator>
struct policy_3_100500 : ternary_policy<100500,Key,Allocator> {};

并使用policy_3_100500 而不是policy_3&lt;100500&gt;

为了更接近您想要的语法,您可以使用嵌套类:

template <time_t Age>
struct policy_3 {
    template <typename Key, template <typename T> class Allocator>
    struct type : ternary_policy<Age,Key,Allocator> {};
};

并使用policy_3&lt;100500&gt;::type 而不是policy_3&lt;100500&gt;

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

template <time_t Age>
struct policy_3 {
    template <typename Key, template <typename T> class Allocator>
    struct bind : ternary_policy<Age,Key,Allocator> {};
};

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

template <typename Key, typename Policy>
struct container {
    typename Policy::template bind<Key,std::allocator<Key>> * _policy;
    // ...
}:

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

【讨论】:

  • 所以五年后,我遇到了完全相同的问题并得出了与您相同的解决方案,但我的代码仍然无法使用expected a class template, got X::type 编译。问题是我将X::type 作为依赖参数传递给另一个模板,所以正确的语法是X::template type。如果只有 gcc 会有更多有用的错误消息。
猜你喜欢
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
相关资源
最近更新 更多