简体   繁体   English

Bool的(部分)模板专业化

[英](partial) template specialization for bool

I'm struggling to understand how template specialization for bool works for this slide taken from cppcon 2017 我正在努力了解bool的模板专业化如何工作于cppcon 2017上的这张幻灯片

Short question: why (first) primary template handles odd N cases when its signature is 简短的问题:为什么(第一)主模板处理奇数 n个个案时,其签名

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

Trying to understand myself I simplified down to 为了了解自己,我简化为

#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>{}();
}

which prints B A , showings same (yet mysterious to me) behavior as linked talk, but if I change template specialization to 会打印出B A ,显示出与链接的谈话相同的行为(对我来说还是很神秘的),但是如果我将模板专用化更改为

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

it prints A B : how compiler chooses between primary S and its specialization? 它打印出A B :编译器如何在主要S及其专业之间进行选择?

The compiler always prefers the specialization over the generalization and thus will always pick it if it can. 编译器总是偏向于专业化而不是一般化,因此,如果可以的话,总是会选择它。

The struct S has a partial template specialization that will only be picked if the second template parameter evaluates to true , so let's see how that works: struct S具有部分模板专业化功能,只有在第二个模板参数的评估结果为true ,才会选择该模板专业化功能。

S<2>{}();

Here the template parameter N is 2 and so 2 % 2 == 0 holds true. 此处模板参数N为2,因此2 % 2 == 0成立。 Which means the specialization will be picked over the generalized S because the specialization requires the second parameter to be true and B is printed. 这意味着将在广义S选择专业化,因为专业化要求第二个参数为true并打印B

This isn't the case for S<3>{}(); S<3>{}();并非如此S<3>{}(); because 3 % 2 == 0 holds false, and thus the generalized case is used, giving you A . 因为3 % 2 == 0成立,所以使用了广义情况,给您A

If you swap it around and make the specialization only accept false for N % 2 == 0 then the results will be the exact opposite, 2 % 2 == 0 still holds true but the specialization only accepts false so it's not picked, 3 % 2 == 0 holds false and thus it will be picked, resulting in AB . 如果将其交换,并使专业化仅接受N % 2 == 0 false ,则结果将完全相反, 2 % 2 == 0仍然成立,但专业化仅接受false,因此不被接受, 3 % 2 == 0保持false,因此将其选中,从而得出AB

It's specialization; 这是专业化; the compiler choose the most specialized version available. 编译器选择可用的最专业的版本。

Ignore for a moment the default value for bool (that transform S<2> in S<2, true> and S<3> in S<3, false> ); 忽略了一会儿默认值bool (即变换S<2>S<2, true>S<3>S<3, false> ); you have 你有

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

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

The first one is neutral regarding the second (the bool one) template parameter; 第一个相对于第二个( bool一个)模板参数是中性的; so matches both S<2, true> and S<3, false> . 因此同时匹配S<2, true>S<3, false>

The second one require that the second template parameter is true , so matches only S<2, true> . 第二个要求第二个模板参数为true ,因此仅匹配S<2, true> And is more specialized than the first one because every match for the second template is also a match for the first one but there are matches for the first one that aren't matches for the second one ( S<3, false> , by example). 并且比第一个模板更专业,因为第二个模板的每个匹配项也都是第一个模板的匹配项,但是第一个模板的匹配项与第二个模板的匹配项不匹配(例如S<3, false> )。

For S<3, false> the compiler find only a template that matches (the first one) so choose the first one. 对于S<3, false> ,编译器仅找到匹配的模板(第一个模板),因此请选择第一个模板。

For S<2, true> the compiler find both templates that match and coose (rule of C++) the most specialized, that is the second one. 对于S<2, true> ,编译器会找到最匹配且匹配的模板(C ++规则),即第二个模板。

When you change the true in false you have that S<3, false> matches both version, so the second one is choosed, and S<2, true> matches only the first one. 当将false更改为true ,您拥有S<3, false>匹配两个版本,因此选择了第二个版本,而S<2, true>仅匹配第一个版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM