C++带方括号的函数调用
C++ function call with square brackets
考虑:
int func(int n)
{
return n;
}
int main()
{
cout << func[4];
cout << func[4, 3, 5];
}
这些实际上意味着什么?我想这是关于访问func+4
,func
在调用func[4]
时分配了空间。
但是,func[4, 3, 5]
简直是荒谬的。
此代码编译并func[4]
不是语法错误的原因是:
1.函数类型可以隐式转换为相同类型的指针。 所以,如果我们有这样的代码:
int f(int);
using func_t = int(*)(int);
void g(func_t);
我们可以写
g(f)
并且不被迫写g(&f)
.&
,将我们从int(int)
型带到int(*)(int)
型隐含地发生。
2.In C(并且必须C++以兼容(指针连接到数组,当p
是指针时p[x]
与*(p + x)
相同。所以func[4]
和*(func + 4)
一样.
3.*(p+x)
具有函数int(int)
的类型,但在必要时也可以隐式衰减为指针类型。所以*(func + 4)
可以隐含地只是(func + 4)
.
4.任何类型的指针都可以流式传输到std::cout
。
请注意,仅仅因为它不是语法错误并不意味着它是有效的。当然,这是未定义的行为,正如 gcc 和 clang 发出的编译器警告所表明的那样,使用函数指针的指针算术通常是错误的,因为您无法创建函数数组。该实现以它喜欢的方式放置函数。(你可以创建一个函数指针数组,但这完全是另一回事。
编辑:我应该纠正自己 - 这个答案并不完全正确。func[4]
无效,因为指针不是指向对象类型的指针。@holyblackcat答案是正确的,请参阅标准中的他的答案以供参考。
这段代码应该是格式不正确的,gcc 只编译它而没有错误,因为它们默认使用非标准扩展。Clang 和 msvc 正确拒绝此代码。
我很惊讶没有答案提到它,但是:
问题中的代码根本无效C++。
它被Clang和MSVC拒绝,没有标志。海湾合作委员会拒绝了它,-pedantic-errors
.
a[b]
(在没有运算符重载的情况下(定义为*(a + b)
,内置运算符+
要求指针操作数是指向对象类型的指针(函数指针不是(。
[expr.add]/1
。两个操作数都应具有算术或无作用域枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整型或无作用域枚举类型。
(强调我的。
GCC 编译代码,因为默认情况下启用了允许对函数指针进行算术的扩展。
由于函数到指针衰减,func[4]
被视为&(&func)[4]
,这实际上意味着&func + 4
,它(如链接所解释的(只是将4
添加到指针的数值中。调用生成的指针很可能会导致崩溃或不可预处理的结果。
std::cout
没有适合打印函数指针的重载<<
,编译器能够找到的最合适的重载是用于打印bool
的重载。指针被转换为bool
,并且由于它是非 null,它变为true
,然后打印为1
。
最后,func[4,3,5]
与func[5]
具有相同的效果,因为在这种情况下,,
被视为运算符,并且x , y
等于y
。
由于尚未提及:func[3, 4, 5]
与func[5]
相同 - 其中的逗号是内置的逗号运算符,它计算左侧表达式,丢弃它,然后计算右侧表达式。此处没有发生函数调用,代码中的逗号也不分隔函数参数。
是的,这是关于访问尚未定义的func+4
,从而导致垃圾值。因此,编译器将用以下警告消息指示您。
hereProgram: In function 'int main()':
Program:7: warning: pointer to a function used in arithmetic
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- C++带方括号的函数调用