我发现这段代码与SFINAE结合在一起:
template<int I> void div(char(*)[I % 2 == 0] = 0) {
// this overload is selected when I is even
}
template<int I> void div(char(*)[I % 2 == 1] = 0) {
// this overload is selected when I is odd
}
它是如何工作的?它看起来像一个未命名的参数数组,但我不明白下标如何帮助解决重载问题。
答案 0 :(得分:7)
C ++中的数组边界不能为零。如果表达式(例如I % 2 == 0
)为false
,则转换为零,从而导致类型无效,从而导致替换失败。
基本上,它是std::enable_if
的混淆版本。
答案 1 :(得分:1)
请记住这是这样称呼的:div<1234>()
=&gt;调用第一个重载。
要理解你只需要查看参数:
char(*)[I % 2 == 0] = 0
这意味着它是指向字符数组的指针。此数组的默认值为0.这意味着您还可以执行char a[] = "hello world"; div<1234>(a);
I % 2 == 0
在编译时进行评估。你应该知道它的作用。即使是整数也是如此,奇数整数使得这个错误。 True计算结果为1,false计算结果为0.但是没有像零元素那样的数组。这就是你所说的SFINAE错误。这并不意味着它是一个根本性的错误,只是模板中的空白无法被充分替代。 模板不匹配。
答案 2 :(得分:0)
如T.C.所述。因为你不能拥有0元素的数组,当条件为假时,布尔值false
被转换为0:类型变为char(*)[0](指向大小为0的char数组的指针)并触发SFINAE。
现在,以更传统(可读)的方式,您通常会让std::enable_if
完成这项工作:
template <int I, std::enable_if_t<I%2>* = nullptr>
div() {
std::cout << "I (" << I <<") am odd." << std::endl;
}
template <int I, std::enable_if_t<!(I%2)>* = nullptr>
div() {
std::cout << "I (" << I <<") am even." << std::endl;
}
正如Coliru所示。