我可以毫无问题地在堆栈上创建可变大小的 C 样式数组:
void f(int n) {
float data1[n]; // OK
}
但我不能对 std::array
做同样的事情:
void f(int n) {
std::array<float,n> data2; // error: ‘n’ is not a constant expression
}
下面的例子更彻底地说明了我的观点:
#include <array>
#include <cstdio>
template<int N>
class A{
public:
void print() {
printf("data[0]: %2.2f\n", data[0]);
}
private:
float data[N];
};
void f(int n) {
float data1[n]; // OK
std::array<float,n> data2; // error: ‘n’ is not a constant expression
A<n> data3; // error: ‘n’ is not a constant expression
}
int main(int argc, char **argv) {
f(3);
}
我的问题:有没有办法严格在堆栈上创建可变大小的类/结构?如果是这样,如何?如果不是,这仅仅是因为规范,还是存在被禁止的潜在技术原因?
最佳答案
你在比较苹果和橙子。
当您使用 variable-length array 时你指的是过去的一个特性(在 C99 中引入),它允许在不知道编译时大小的情况下专门在堆栈上分配数组。这是由编译器通过在运行时保留所需的堆栈大小而不是之前预先计算位移来完成的。
如果我没记错的话,它实际上在 C++11 中被降级为可选功能(而 C11 则带来了它)。
然后你有std::array<T,size_t>
这是完全不同的东西。这是一个template
并且需要使用编译时类型/值进行实例化。所以你根本无法做你想做的事。
要点是 C++ 是一种允许您避免需要 VLA 的语言,因为您有 std::vector
和动态分配。
如果你真的想在堆栈上分配东西,你必须寻找 99.9% 的时间不需要的特定和肮脏的技巧,比如 placement new 和 alloca
(这在任何情况下都是非标准的),例如:
void *reserved = alloca(sizeof(MyClass));
new (reserved) MyClass();
关于c++ - 堆栈上的可变大小对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36562685/