C ++方括号语法

时间:2020-09-29 09:14:13

标签: c++

在有关SFINAE的cppreference文章中,我遇到了我不理解的这种语法:

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
}

我知道它是一个模板函数声明,但是我不明白参数的含义。特别是char(*)[I % 2 == 0] = 0中的方括号是什么,为什么它等于0?

2 个答案:

答案 0 :(得分:6)

在C ++中,大小为0的数组是非法的,因此根据I的值选择特定的重载:当I为5时,char(*)[I % 2 == 0]将是一个指向数组的指针。大小false,即零,而另一个数组指针完全合法。

= 0只是默认的忽略参数值,可避免您每次调用此函数时键入(0)

在C ++ 20中,它将更加明显和直接:

template<int I> requires (I % 2 == 0) void div() {
}

甚至在C ++ 17中:

template<int I> void div() {
    if constexpr(I % 2 == 0) {
    }
    else {
    }
}

答案 1 :(得分:1)

I达到偶数时(记住false转换为0true转换为1):

template <int I> void div(char(*)[1] = 0) {
        // this overload is selected when I is even
}
template <int I> void div(char(*)[0] = 0) {
        // this overload is selected when I is odd
}

第二次尝试使用大小为0并根据该page上的项目符号点的数组:

以下类型错误是SFINAE错误:

    试图创建一个空数组,引用数组,函数数组,数组 负数,非整数大小的数组,或零大小的数组

...触发SFINAE,并选择第一个过载。当0为奇数时,第一个重载的数组大小为I。请注意,该参数未命名。它不在函数内部使用,其唯一目的是触发SFINAE。调用此函数不需要传递参数,因为它具有默认值,即=0。传递参数将毫无用处,因为无论如何都不会使用其值。

这是SFINAE的相当神秘的示例。从C ++ 11开始,您可能将std::enable_iftemplate <int I> is_odd;或类似名称一起使用,并且从C ++ 20开始,您将使用概念。

相关问题