C++ 对这种语法感到困惑

C++ 对这种语法感到困惑,c++,function,C++,Function,当我在cppreference.com上阅读关于SFINAE的文章时,我遇到了一段我无法理解的片段: template <int I> void div(char(*)[I % 2 == 0] = 0) 它看起来像指向返回char的函数的指针,但带bool的方括号是什么。它是真实的还是只是一些愚蠢的人工示例?char(*)[I%2==0]=0是大小为1的字符数组上的指针,当I为偶数时为1,当I为奇数时为0,指针默认为0 由于无法创建大小等于0的数组,因此只能在I甚至为时调

当我在cppreference.com上阅读关于SFINAE的文章时,我遇到了一段我无法理解的片段:

    template <int I> void div(char(*)[I % 2 == 0] = 0) 
它看起来像指向返回char的函数的指针,但带bool的方括号是什么。它是真实的还是只是一些愚蠢的人工示例?

char(*)[I%2==0]=0
是大小为1的字符数组上的指针,当I为偶数时为1,当I为奇数时为0,指针默认为0


由于无法创建大小等于0的数组,因此只能在I甚至为

时调用此重载。如果将参数名称放入:

void div(char (*x)[I % 2 == 0] = 0)
x
是指向大小为
1
(对于true)或
0
(对于false)的数组的指针,默认为
nullptr


但C++中参数名是可选的,所以如果函数不使用代码> x<代码>,它就可以省略这个名称。

你所看到的是旧式风格的sFiAe。< /P> 背景: SFINAE:替换失败不是错误

当您尝试实例化模板时,它会检查模板是否可以在没有错误的情况下实例化。如果发生错误,则什么也不会发生,当前尝试的模板将被忽略。通常,您有两个或多个模板定义,但一次只能实例化一个,而不会出现错误

在您的例子中,将创建一个数组,如果I为偶数,则结果是大小为零的数组。这是一个编译错误,但作为模板声明使用时,它被允许失败并将被忽略。因此,您可以使用这样的语句根据参数选择要实例化的模板

详细语法如下:

template <int I> void div(char(*)[I % 2 == 0] = 0)
模板无效div(char(*)[I%2==0]=0)
我们有一个模板,接受一个参数:inti。 然后模板定义一个函数,该函数获取指向大小为“I%2==0”的字符数组的指针,从而导致逻辑从bool转换为int。因此,如果我是偶数,结果是零->SFINAE将失败,实例被忽略,如果我是奇数,则得到true->转换为1。这意味着您将创建一个指向大小为1的字符指针数组的指针。好的,将创建实例。拥有指针后,它将默认初始化为0

在这里,我们可以使用偶数或奇数I来选择将实例化这两个(或更多)模板中的哪一个


在更多的“现代”C++中,我们看到STD::EnabLEY~如果要选择哪个模板将被实例化。这使它更具可读性。但是C++之前11 C++没有这个。因此,为SFINAE生成错误的需要通常是通过创建大小为负或零的数组来完成的。这是SFINAE在旧式代码中常见的一种攻击。

下面有一条注释解释了它的用途:
//当我理解了它的用途时,这个重载就被选中了。我不知道的是数组指针的语法。谢谢。指向某个语法数组的指针对我来说是未知的。这是一个指向数组的指针:
int(*)[]
,这是一个指向函数的指针:
int(*)(
?@griezmanlol,这是正确的。另一方面,
int*[]
是指针数组,
int*()
是返回指针的函数。太好了。谢谢你的回答。
template <int I> void div(char(*)[I % 2 == 0] = 0)