[英](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.