我们可以通过一些合法的方式在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) ();
是合法解析函数原型的方法?以这种方式声明函数有什么特别的意义吗?或者它是否像其他任何函数声明一样正常工作?
答案 0 :(得分:11)
一个区别是将它括在括号中会阻止预处理器进行类似函数的宏扩展。正如其他答案中所提到的,它与实际的编译器没有区别。
例如:
// 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库背后的聪明人决定为min
和max
之类的东西提供类似函数的宏时。 (还有其他方法,比如#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)
,它将不会尝试扩展它(它会忽略它)。这只是一个规则。
答案 1 :(得分:3)
与
相同void function();
您可以将其声明为
void ((function)) ();
如果你想:)
注意不要将它与函数指针声明语法混淆。
答案 2 :(得分:0)
我想你可能会发现:
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
。
答案 3 :(得分:0)
没有什么特别之处,它与没有括号的版本完全相同。它只是声明语法的工件。通常,当声明函数指针时,您会看到在函数名称周围使用括号,例如
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*
答案 4 :(得分:0)
我认为它与普通函数的作用相同,因为函数指针被声明为:void (*function)()
,所以如果省略*
那么它应该只是一个函数。
答案 5 :(得分:0)
它对应于C ++语法。如果要简化,那么定义声明符的规则之一就是
declarator:
(declarator)
所以你可以写例如
void (function) ();
或
void ( (function) () );
甚至以下方式
struct A
{
void ( ( function )() const );
};