我需要一双新鲜的眼睛。

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

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

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

有没有办法包装T或做一些棘手的事情,以便这种事情可以起作用?

谢谢!

最佳答案

是的,您可以使用以下技巧:

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

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

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

编辑:第三个参数到底意味着什么?好吧,它是默认值,它是0。例如,当我们将名称命名为Foo<int, 5>时,它将通过。但是实际上,我们使用参数Foo<int, 5, 0>实例化了模板,因为最后一个是默认参数。当第三个参数与第三个参数匹配时,部分特化匹配(默认情况下为零),并且如果第三个参数和第二个参数相同,因为它们都是t,则部分特殊化匹配。

上面的技巧有一个缺点,即Foo<int, 9, 9>也使用我们的特化技术。但另一方面,上面的操作非常简单,因此您可能可以摆脱它。如果您不希望它起作用,那么可以使用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<int, 9, void>,也不会选择我们的部分特化,因为条件t == 0不正确,因此::type将不可用。 SFINAE当时没有选择专业。当然,使用此enable_if解决方案,您不仅限于t为零。任何条件都可以。作为引用,如果您不使用boost,这是enable_if的代码。然后剪切上面的_c后缀,下面的版本就不需要了:
template<bool C, typename T = void>
struct enable_if {
  typedef T type;
};

template<typename T>
struct enable_if<false, T> { };

关于c++ - 部分特化问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/467335/

10-13 03:07