声明类型为 void C++ 的函数数组
Declaring an array of functions of type void C++
我有一些 return void
的功能。我指向这些函数并希望得到这些函数的数组:
此代码为何有效:
#include <cstdio>
using std::puts;
void tell() {
puts("hi");
};
void slap() {
puts("goodbye");
}
int main(int argc, char *argv[])
{
void (*tp)() = tell;
void (*sp)() = slap;
void(*funcs[])() = {tp, sp};
for (auto point:funcs) {
point();
}
return 0;
}
当我在 funcs
(即 void(funcs[])() = {tp, sp};
中没有指定指针的情况下尝试此代码时,我得到 " error: 'funcs' declared as array of functions of type 'void ()' "
这正是它们的含义 - 那么为什么会出现错误?
我也不懂语法,void(*funcs[])()
末尾的()
不是表示实际调用函数吗?
C++ 标准 8.3.5/10 说:
There shall be no arrays of functions, although there can be arrays of pointers to functions.
必须使用 "spiral rule":
读取“funcs
”的声明
funcs[]
: funcs
是一个数组
*funcs[]
: funcs
是一个指针数组
(*funcs[])()
: funcs
是指向无参数函数的指针数组
void (*funcs[])()
: funcs
是指向函数的指针数组,不带参数返回 void
.
没有星号,void (funcs[])()
声明一个函数数组而不是 指针数组 函数。后者在 C++ 语法中是允许的,而前者是不允许的。
[dcl.array]/p1:
T
is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) type void
, a function type or an abstract class type.
初始化列表 ({tp, sp}
) 的内容是函数,但它们通过函数到指针的转换被转换为指针:
[conv.func]/p1
An lvalue of function type T
can be converted to a prvalue of type “pointer to T
.” The result is a pointer to the function.
请注意,C++ 也不允许引用数组。
I also don't get the syntax, wouldn't the ()
at the end of void(*funcs[])()
indicate actually calling a function?
不是,这是数组类型的声明。 ()
是指定函数参数列表的类型构造的一部分。整个类型表示"an array of pointers to functions which take zero arguments (()
) and return void
"。使用类型别名可能会变得更清楚:
using void_f = void (*)();
void_f funcs[] = {tp, sp};
这样使用:
int main(int argc, char *argv[])
{
void (*tp)() = tell;
void (*sp)() = slap;
void (*funcs[])() = {tp, sp};
for (void (*point)():funcs)
{
point;
}
return 0;
}
好吧,你可以像这样明确地声明它:
void (*actions[5])();
但这几乎不可读。
为了使其更具可读性,请使用 typedef。
typedef void(*Action)(); // Action is the typename for a pointer
// to a function return null and taking
// no parameters.
Action actions[5]; // An array of 5 Action objects.
或者为了您的目的:
int main()
{
Action actions[] = {&tell, &slap};
}
我有一些 return void
的功能。我指向这些函数并希望得到这些函数的数组:
此代码为何有效:
#include <cstdio>
using std::puts;
void tell() {
puts("hi");
};
void slap() {
puts("goodbye");
}
int main(int argc, char *argv[])
{
void (*tp)() = tell;
void (*sp)() = slap;
void(*funcs[])() = {tp, sp};
for (auto point:funcs) {
point();
}
return 0;
}
当我在 funcs
(即 void(funcs[])() = {tp, sp};
中没有指定指针的情况下尝试此代码时,我得到 " error: 'funcs' declared as array of functions of type 'void ()' "
这正是它们的含义 - 那么为什么会出现错误?
我也不懂语法,void(*funcs[])()
末尾的()
不是表示实际调用函数吗?
C++ 标准 8.3.5/10 说:
There shall be no arrays of functions, although there can be arrays of pointers to functions.
必须使用 "spiral rule":
读取“funcs
”的声明
funcs[]
: funcs
是一个数组
*funcs[]
: funcs
是一个指针数组
(*funcs[])()
: funcs
是指向无参数函数的指针数组
void (*funcs[])()
: funcs
是指向函数的指针数组,不带参数返回 void
.
没有星号,void (funcs[])()
声明一个函数数组而不是 指针数组 函数。后者在 C++ 语法中是允许的,而前者是不允许的。
[dcl.array]/p1:
T
is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) typevoid
, a function type or an abstract class type.
初始化列表 ({tp, sp}
) 的内容是函数,但它们通过函数到指针的转换被转换为指针:
[conv.func]/p1
An lvalue of function type
T
can be converted to a prvalue of type “pointer toT
.” The result is a pointer to the function.
请注意,C++ 也不允许引用数组。
I also don't get the syntax, wouldn't the
()
at the end ofvoid(*funcs[])()
indicate actually calling a function?
不是,这是数组类型的声明。 ()
是指定函数参数列表的类型构造的一部分。整个类型表示"an array of pointers to functions which take zero arguments (()
) and return void
"。使用类型别名可能会变得更清楚:
using void_f = void (*)();
void_f funcs[] = {tp, sp};
这样使用:
int main(int argc, char *argv[])
{
void (*tp)() = tell;
void (*sp)() = slap;
void (*funcs[])() = {tp, sp};
for (void (*point)():funcs)
{
point;
}
return 0;
}
好吧,你可以像这样明确地声明它:
void (*actions[5])();
但这几乎不可读。
为了使其更具可读性,请使用 typedef。
typedef void(*Action)(); // Action is the typename for a pointer
// to a function return null and taking
// no parameters.
Action actions[5]; // An array of 5 Action objects.
或者为了您的目的:
int main()
{
Action actions[] = {&tell, &slap};
}