繁体   English   中英

不寻常的C ++函数声明

[英]Unusual C++ function declaration

我们可以通过一些合法的方式在C ++中声明一个函数。

一些合法的方式是:

void function ();
void function (void);
dataType function (dataType);

and so on...

最近,我遇到了一个函数声明:

void (function) ();  //Take note of the braces around the function name

我以前从未见过像这样的东西,当我在C ++编译器中测试它时,它运行时没有任何警告或编译错误。

我的问题是 :为什么是void (function) (); decalre函数原型的合法方法? 以这种方式声明函数有什么特别的意义吗? 或者它是否像其他任何函数声明一样正常工作?

一个区别是将它括在括号中会阻止预处理器进行类似函数的宏扩展。 正如其他答案中所提到的,它与实际编译器没有区别。

例如:

// somewhere buried deep in a header
#define function(a, b) a + b

// your code
void function() {  // this expands the macro and gives compilation error
}

void (function)() { // this does not expand and works as expected
}

这很方便,例如当Microsoft Visual Studio库背后的聪明人决定为minmax类的东西提供类似函数的宏时。 (还有其他方法,比如#undef )。

请注意,仍然会扩展类似对象的宏(例如#define function 3 + 4 )。


预处理器只是一个愚蠢的文本替换工具(而不是编译器,它只是一个(智能)文本替换工具)。 它采用宏定义并在任何地方替换它。 他不知道他所取代的语义。

例如:

// somewhere buried deep in a header
#define function 3 + 2

// your code
void function() {
}

预处理器看到单词function并在文本上用字符串3 + 2替换它。 他不知道function是函数声明和定义的id-name部分。 在预处理阶段之后出现了实际的编译阶段。 所以编译器实际看到:

// your code
void 3 + 2() {
}

这对他没有任何意义并给出错误。

对于类似函数的宏

// somewhere buried deep in a header
#define function(a, b) a + b

预处理器执行相同的操作,只是它期望括号括在括号中的两个'标记'用逗号(参数)分隔并进行替换。 (再次没有语义意识):

int d = function(2, 3);
//will be replaced by the preprocessor to:
int d = 2 + 3; // passes compilation phase

void function();
// the preprocessor doesn’t find the arguments for function so it gives an error.

但是如果它遇到(function)它将不会尝试扩展它(它忽略它)。 这只是一个规则。

它是一样的

void function();

你可以声明它

void ((function)) ();

如果你想 :)

注意不要将它与函数指针声明语法混淆。

我想你可能会发现:

void (*function) ();

因为使用void (function)();没有任何好处void (function)(); void (((((function)))))(); 就此而言,它们是等同的。 如果我错了并且它不是拼写错误,那么答案是你可以根据编译器的限制在函数名称周围放置尽可能多的括号,根据下面的output6()代码。

如果我没有弄错的话,带有*那个实际上声明了一个函数指针 ,可用于保存指向函数的指针。 它根本不声明一个函数,只是一个可用于引用函数的指针。

int指针(例如)一样,函数指针可以指向任意函数,参数不合适。

例如:

#include <iostream>

void (((((output6)))))() { std::cout << 6; }
void output7() { std::cout << 7; }
void output8() { std::cout << 8; }
void (*fn)();

int main() {
    fn = &output6; fn();
    fn = &output7; fn();
    fn = &output8; fn();
    std::cout << '\n';
}

输出678

没有什么特别之处,它与没有括号的版本完全相同。 它只是声明语法的工件。 通常,当声明函数指针时,您会看到函数名称周围使用括号,例如

void (*function_pointer)() = nullptr;
// a function pointer to a function taking and returning void

相比之下

void *function();
// a function declaration of a function taking void and returning void*

我认为它与普通函数的作用相同,因为函数指针声明为: void (*function)()所以如果省略*那么它应该只是一个函数。

它对应于C ++语法。 如果要简化,那么定义声明符的规则之一就是

declarator:

   (declarator)

所以你可以写一些例子

void (function) (); 

要么

void ( (function) () );

甚至以下方式

struct A
{
   void ( ( function )() const );
};   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM