我想动态分配一个函数指针数组。这是我的一些尝试:
<xsl:stylesheet>
我不知道为什么#include <type_traits>
void f(int n) {
// auto p1 = new void(*[n])(); // syntax error
auto p2 = new (void(*[n])()); // warning, see below
auto p3 = new typeof(void(*)())[n]; // non-standard extension
using fptr = void(*)(); auto p4 = new fptr[n]; // verbose, but okay
auto p5 = new std::add_pointer_t<void()>[n]; // hackish
}
会导致警告,因为我不能在没有括号的情况下写警告(例如在p2
中)?
(gcc)警告:必须指定非常量数组新长度,而不能 在类型ID [-Wvla]周围的括号
(clang)警告:当类型在括号中时,数组不能包含 动态尺寸
这是一个纯粹的理论问题。我不是在寻找如何编写解决问题的良好代码的建议。
答案 0 :(得分:4)
有一种无需某种类型别名即可编写此表达式的方法。但这不值得。
new-expression 的语法是
new-expression :
::
opt 新安置 opt new-type-id 新初始化器 opt
::
opt 新放置 opt {{ 1}} type-id(
新初始化器 optnew-type-id :
type-specifier-seq 新声明符 opt
新声明符:
ptr-operator 新声明符 opt
noptr-new-declarator
ptr-operator :
)
attribute-specifier-seq opt cv-qualifier-seq opt
*
attribute-specifier-seq opt
&
attribute-specifier-seq opt嵌套名称说明符
&&
属性说明符-seq opt cv-qualifier-seq optnoptr-new-declarator :
*
表达式[
属性说明符-seq opt >noptr-new-declarator
]
constant-expression[
attribute-specifier-seq opt
new-type-id 中使用的 new-declarator 语法符号类似于 type中使用的 abstract-declarator 符号-id ,有三个重要区别:
new-declarator 允许在第一组方括号之间使用非恒定表达式,以指定动态创建大小可变的数组。 type-id 并不是因为“ ]
是常量表达式”时,“大小为T
的数组N
”仅是有效的C ++类型。
type-id 允许将 ptr-abstract-declarator 括在括号中,以帮助指定指针数组或函数指针类型,和/或将功能参数列表括在括号中以指定功能类型。 new-declarator 根本不允许任何括号! N
关键字后的任何括号都指定 new-placement 或带括号的 type-id 或 new-initializer 。 (我想如果 new-type-id 也可能包含括号,则将所有这些东西的组合消除歧义会非常混乱。)
type-id 允许new
省略号标记出现在实际声明具有标识符的位置。此处并不相关,但这允许使用未命名的函数参数包,例如...
因此使用 type-id 的 new-expression 表单不允许使用示例函数所需的可变大小。使用 new-type-id 的 new-expression 形式在其语法树中根本不允许任何函数参数列表,因此必须在其中引入任何函数类型 type-specifier-seq 。我认为可能是 type-name , decltype-specifier 或 typename-specifier 。
所以我想 decltype-specifier 选项的确为我们提供了另一种愚蠢的写表达式方式,但这一次不需要命名别名或template<class T> void f(T...);
。
#include