bool的(部分)模板专业化

时间:2017-11-05 17:18:59

标签: c++ templates

我很难理解bool的模板特化如何适用于cppcon 2017

的幻灯片

简短问题:为什么(第一个)主要模板在签名

时处理奇数 N个案例

< ...,bool = (N%2 == 0)> ?

试图了解自己,我简化为

#include<iostream>
template<unsigned N, bool =(N%2==0)> struct S { void operator()(){ std::cout << "A\n"; } };
template<unsigned N> struct S<N, true> { void operator()(){ std::cout << "B\n"; } };
int main()
{
    S<2>{}();
    S<3>{}();
}

打印B A,显示与链接谈话相同(但对我来说神秘)行为,但如果我将模板专精化更改为

template<unsigned N> struct S<N, false> { void operator()(){ std::cout << "B\n"; } };
                                 -----

它打印A B:编译器如何在主S及其专业化之间进行选择?

2 个答案:

答案 0 :(得分:1)

编译器总是更喜欢泛化的特化,因此如果可以,它总是会选择它。

struct S有一个部分模板特化,只有在第二个模板参数的计算结果为true时才会被选中,所以让我们看看它是如何工作的:

S<2>{}();

此处模板参数N为2,因此2 % 2 == 0成立。这意味着将在广义S上挑选专业化,因为专业化要求第二个参数为true并打印B

S<3>{}();不是这种情况,因为3 % 2 == 0保持为false,因此会使用广义情况,为您提供A

如果你交换它并使专门化只接受false N % 2 == 0,那么结果将完全相反,2 % 2 == 0仍然成立,但专业化只接受假,所以它是未选中,3 % 2 == 0保持为假,因此会被选中,从而产生A B

答案 1 :(得分:0)

它的专业化;编译器选择最专业的版本。

暂时忽略bool的默认值(S<2>中的S<2, true>S<3>中的S<3, false>转换;你有

template <unsigned N, bool>
struct S
 { /* something */};

template <unsigned N>
struct S<N, true>
 { /* something */};

关于第二个(bool one)模板参数,第一个是中性的;所以匹配S<2, true>S<3, false>

第二个要求第二个模板参数为true,因此仅匹配S<2, true>。并且比第一个模板更专业,因为第二个模板的每个匹配也匹配第一个模板,但是第一个模板的匹配不匹配第二个模板(S<3, false>,例子)。

对于S<3, false>,编译器只找到匹配的模板(第一个),所以选择第一个。

对于S<2, true>,编译器会找到最匹配和最具特色的模板(C ++规则),即第二个模板。

当您更改true false时,S<3, false>匹配两个版本,因此选择第二个版本,S<2, true>仅匹配第一个版本。< / p>