解构表达式
Deconstructing the expression
参照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?
感谢您的想法。
如果我们像 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
}
长度为零的数组是ill-formed,所以第一个版本是替换失败。它已从重载决议中删除。第二个版本没问题,所以它参与了重载决议。因此,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
}
零长度数组是ill-formed,所以第二个版本是替换失败。它已从重载决议中删除。第一个版本没问题,所以它参与了重载决议。因此,div<42>
调用第一个重载。
从 C++17 开始,我们可以使用 if constexpr
结构使代码更容易理解:
template <int I>
void div()
{
if constexpr (I % 2 == 0)
/* handle even case */;
else
/* handle odd case */;
}
参照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?
感谢您的想法。
如果我们像 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
}
长度为零的数组是ill-formed,所以第一个版本是替换失败。它已从重载决议中删除。第二个版本没问题,所以它参与了重载决议。因此,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
}
零长度数组是ill-formed,所以第二个版本是替换失败。它已从重载决议中删除。第一个版本没问题,所以它参与了重载决议。因此,div<42>
调用第一个重载。
从 C++17 开始,我们可以使用 if constexpr
结构使代码更容易理解:
template <int I>
void div()
{
if constexpr (I % 2 == 0)
/* handle even case */;
else
/* handle odd case */;
}