【问题标题】:Partial Specialization Question部分专业化问题
【发布时间】:2009-01-21 22:36:04
【问题描述】:

我需要一双新鲜的眼睛。

这显然是非法的,但它显示了我正在尝试做的事情:

template <typename T, T> struct Foo
{
};

template <typename T> struct Foo <T, 0> //Obviously I can't do this.
{
};

有没有什么方法可以包装 T 或做一些棘手的事情以便这种事情可以工作?

谢谢!

【问题讨论】:

    标签: c++


    【解决方案1】:

    是的,你可以使用这个技巧:

    template <typename T, T, T=0> struct Foo {
    };
    
    template <typename T, T t> struct Foo <T, t, t> {
    };
    

    如果特化中 t 为 0,它将匹配默认参数,并采用特化。否则,将采用主模板。

    编辑:第三个​​参数到底是什么意思?嗯,它是一个默认值,它是 0。例如,当我们将专业化命名为 Foo&lt;int, 5&gt; 时,它将被传递。但实际上,我们使用参数Foo&lt;int, 5, 0&gt; 实例化了一个模板,因为最后一个参数是默认参数。偏特化匹配,当第三个参数匹配第三个参数时,默认为零,如果第三个和第二个参数相同,因为都是t

    上述技巧的缺点是Foo&lt;int, 9, 9&gt; 也使用了我们的特化。但另一方面,上述内容非常简单,因此您可能会逃脱惩罚。如果你不希望它工作,那么你可以使用enable_if,这有点复杂:

    template <typename T, T, typename = void> struct Foo {
    };
    
    template <typename T, T t> 
    struct Foo <T, t, typename boost::enable_if_c< t == 0 >::type> {
    };
    

    现在,即使您说Foo&lt;int, 9, void&gt;,也不会选择我们的部分特化,因为条件t == 0 不正确,因此::type 将不可用。 SFINAE当时没有选择专业化。当然,使用此 enable_if 解决方案,您不仅限于 t 为零。任何条件都可以。作为参考,这里是 enable_if 的代码,如果你不使用 boost。把上面的_c后缀剪掉,下面的版本就不需要了:

    template<bool C, typename T = void>
    struct enable_if {
      typedef T type;
    };
    
    template<typename T>
    struct enable_if<false, T> { };
    

    【讨论】:

    • 第三个参数只是为了在其中获取 T 类型的值 0。如果您想专门针对两个值(例如 0 和 1),则必须使用 boost::enable_if 文档中描述的类型参数,对吗?
    • 是的,没错。像这里的一样,条件必须是分离的,以免您产生歧义:stackoverflow.com/questions/267418/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多