参考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
}
假设我是偶数,我正在尝试读取此重载解决方案,并遵循运算符优先级规则:
deconstruct 1: template<int I> div(char (*) [1] = 0) //since I % 2 == 0
因此,阅读以下内容是否正确:
模板函数div
需要一个函数指针参数,其签名为char (*) [int I = 1]
,默认为0还是NULL?
欣赏您的想法。
答案 0 :(得分:1)
如果我们像div<21>
这样称呼它,则编译器会尝试将I = 21
替换为模板。我们得到:(__div21
是替换产生的假设函数的名称)
void __div21(char(*)[0] = 0) {
// this overload is selected when I is even
}
void __div21(char(*)[1] = 0) {
// this overload is selected when I is odd
}
长度为零的数组格式错误,因此第一个版本是替换失败。从重载解决方案中将其删除。第二个版本很好,因此它参与了重载解析。因此,div<21>
调用第二个重载。
如果我们像div<42>
这样称呼它,则编译器会尝试将I = 42
替换为模板。我们得到:(__div42
是替换产生的假设函数的名称)
void __div42(char(*)[1] = 0) {
// this overload is selected when I is even
}
void __div42(char(*)[0] = 0) {
// this overload is selected when I is odd
}
长度为零的数组格式错误,因此第二个版本是替换失败。从重载解决方案中将其删除。第一个版本很好,因此它参与了重载解析。因此,div<42>
会调用第一个重载。
从C ++ 17开始,我们可以使用if constexpr
构造使代码更容易理解:
template <int I>
void div()
{
if constexpr (I % 2 == 0)
/* handle even case */;
else
/* handle odd case */;
}