我需要一双新鲜的眼睛。
这显然是非法的,但它表明了我正在尝试做的事情:
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/