【问题标题】:Partial default specialization of multiple parameter template多参数模板的部分默认特化
【发布时间】:2013-11-11 23:39:51
【问题描述】:

有没有办法从编译器中提取部分默认特化?

说我有这两个参数模板:

template<typename A, typename B>
struct X {
    A a;
    B b;
};

我还有一些使用单个参数模板的代码,如下所示:

template<template<typename> class T, typename B>
struct make_T_of_B {
    T<B> member;
};

我想说:

make_T_of_B<X<int>, double> dummy;

其中 X 被视为单个参数模板。它相当于这个模板:

template<typename B>
struct Y {
    int a;
    B b;
};

看起来就像一个人如何专门化 X 而不实际改变任何东西。它在某种程度上类似于默认特化——除了默认特化不产生另一个模板而是产生一个实际类型(换句话说,它总是总计)。

我意识到我可以级联模板参数

template<typename A>
struct Z1 {
    // start from scratch
    template<typename B>
    struct Z2 {
        A a;
        B b;
    };

    // inherit from double template above
    template<typename B>
    struct X: ::X<A, B> {}; 
};


make_T_of_B<Z1<int>::Z2, double> dummy1;
make_T_of_B<Z1<int>::X, double> dummy2;

但我发现这很难阅读并且无法清楚地传达我的意图。

谢谢。

【问题讨论】:

  • template &lt;typename T&gt; using Foo = X&lt;int, T&gt;; 怎么样?现在您可以使用Foo&lt;double&gt; 并获得X&lt;int, double&gt;
  • 是的,谢谢,这就是我想要的。这是我无法访问的 C++11 功能,但它完美地回答了这个问题。我愿意接受这个——如果它是一个答案……
  • 我添加了第二个答案。

标签: c++ templates template-templates


【解决方案1】:

我误解了你的问题。你想要的只是一种绑定第一个模板参数的方法,你可以像这样轻松地做到这一点:

template <typename T> using Foo = X<int, T>;

现在Foo&lt;double&gt;X&lt;int, double&gt; 相同。

如果没有 C++11 风格的别名,您可以使用更多样板来实现相同的效果:

template <typename T> struct Foo
{
    typedef X<int, T> type;
};

现在你使用Foo&lt;double&gt;::type

【讨论】:

  • 只是一个非常小的挑剔:第二个建议,虽然在大多数情况下完全可以接受,但不能真正适用于make_T_of_B,没有什么可以实例化make_T_of_B 最终产生@987654328 @.
【解决方案2】:

我会使用一个特质:

template <typename> struct applicator;

template <template <typename> class Tmpl, typename T>
struct applicator<Tmpl<T>>
{
    template <typename A>
    using rebind = make_T_of_B<Tmpl, A>;
};

现在你可以说:

applicator<X<int>>::rebind<double> dummy;

您当然也可以将第二个参数A 移动到主模板中:

template <typename, typename> bpplicator;

template <template <typename> class Tmpl, typename T, typename A>
struct bpplicator<Tmpl<T>, A>
{
    using type = make_T_of_B<Tmpl, A>;  // or "typedef make_T_of_B<Tmpl, A> type;"
};

bpplicator<X<int>, double>::type dummy;

它的优点是它也适用于 C++03。

【讨论】:

  • 你也可以尝试继承:struct bpplictor&lt;Tmpl&lt;T&gt;, A&gt; : make_t_of_B&lt;Tmpl, A&gt; 这样你就不需要using 别名了。
  • @0x499602D2:但是你会得到一个不同的类型。使用我的方法,您实际上得到的类型与您所说的 make_T_of_B&lt;X, double&gt; 相同。
  • X(我写它的方式)是一个双参数模板,所以X&lt;int&gt; 永远不会被成功解析,或者至少,它不适合我。我可能没有说清楚,但我想要的是通过修复它的第一个参数从双参数模板中获取一个参数模板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
相关资源
最近更新 更多