目前,我正在使用 gcc,它允许在 C++ constexpr 函数中使用 C 可变长度数组(不要问我为什么)。当然,这不是标准行为,但会产生预期的效果。
我正在寻找更多在其他编译器中模拟所需行为的方法。作为标准后备方案,我添加了一个使用 unique_ptr 的选项,从而在不支持 constexpr 和变量堆栈分配的平台上模拟 gcc 的行为。
这是我到目前为止得到的:
class Integer {
private:
int i;
public:
constexpr
Integer(const int& _t = 10)
: i(_t)
{ }
constexpr int
get(void) const {
return i;
}
};
#if defined(__GNUC__) && !defined(__clang__)
#define XALLOC(type, name, count) type name[count]
#else
#include <memory>
#define XALLOC(type, name, count) std::unique_ptr<type[]> __##name(new type[count]); type* name = &__##name[0]
#endif
constexpr
int t(int num) {
XALLOC(Integer, i, num);
return i[0].get();
}
constinit int nu = t(10);
int main(int argc, const char *argv[]) {
return t(0);
}
我不知道这是否适用于
constexpr
函数(还没有尝试过),但在大多数 *nix 平台上,您可以在堆栈上分配任意数量的空间(好吧,在某种程度上.. .) 与 alloca
,例如
void foo ()
{
int *my_stuff = (int *) alloca (42);
// Do things with my_stuff, it will go away automatically when `foo` returns
}
为了简洁起见,使用了 C 风格的转换,MSVC 等效项是
_alloca
(您可以使用简单的条件定义宏来解决)。
请注意,Windows 堆栈只有 1MB(尽管有一个链接器标志可以增加它),所以请注意您的操作方式。 Linux 和其他系统是 8MB,但同样,可能有一种方法可以对其进行调整(并且,在 64 位版本中,没有真正的理由不这样做)。
VLA 是非标准的,有点邪恶,不要使用它们。