解构表达式

时间:2019-07-19 03:33:01

标签: c++ syntax sfinae

参考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?

欣赏您的想法。

1 个答案:

答案 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 */;
}