如何使用 const 成员变量设置数组大小?

How to set array size with const member variable?

我尝试使用 const 成员变量设置数组大小,如下所示

class A {
  const int SIZE;

  A() : SIZE(10) {}
  void aaa() { int a[SIZE]; }
};

我无法构建

a[SIZE]

喜欢这个表情

当我使用GCC时,构建成功。但是当我使用 VC++ (Windows) 时,我无法构建。

错误信息是“'this'不能用在常量表达式中”

如何使用const成员变量设置数组大小?

嗯,SIZE 可能不是宏,因为在这里,您用 10 初始化它并将其作为变量。如果它是一个宏,你的表达式 int a[SIZE] 会起作用,但你无论如何都不需要第 2-4 行。

如果 SIZE 在这里是一个普通变量(包括使用大小参数动态创建 A 虽然 输入可能来自一个宏),你应该使用一个向量。

#include <vector>

class A {
  const int SIZE;

  A() : SIZE(10) {}
  void aaa() { std::vector<int> a(SIZE); }
};

a 的用法现在相同。

可变长度数组

when I use VC++ (Windows), I cannot build.

一个数组 int a[SIZE] 被创建在堆栈上,具有自动存储持续时间。 那么这个 SIZE 通常必须在 C++ 的编译时确定。 但是您的 SIZE 定义为没有值,如下所示:

const int SIZE;

因此编译器无法在编译时知道它的值,并会显示编译错误。 所以你的 SIZE 是一个动态变量。

When I use GCC, build success.

...但是一些 C++ 编译器支持 VLA(可变长度数组),它是 C99 的补充,允许在堆栈上声明具有动态长度的 C 样式数组。 VC++不支持C99和VLA,但是GNU compiler supports VLA as an extension even in C90 and C++这就是为什么你可以通过GCC无错编译以上代码的原因。

如果在 gcc 编译命令中添加 -pedantic (-pedantic-errors) 选项,我们可以得到大多数 gcc 扩展的警告(错误)。 在这种情况下,使用此选项我们应该得到警告(错误)消息:ISO C++ forbids variable length array 'a'.


如何修复当前错误?

(1) 如果您想使用 C 风格的数组,一种方法是使 SIZE 成为一个宏,如下所示。然后编译器可以在编译时知道它的值:

#define SIZE 10

class A
{
public:
  A() {}
  void aaa() { int a[SIZE]; }
};

(2) 在 class 定义中将 SIZE 的值定义为 static const 变量,然后编译器可以在编译时再次知道它的值:

class A
{
  static constexpr int SIZE = 10;

public:
  A() {}
  void aaa() { int a[SIZE]; }
};

(3) C++ 通过 std::vectorstd::array 提供数组功能,这可能使我们的代码更具可读性、可移植性和健壮性。 我希望堆栈上的 std::array 比你的情况下的 std::vector 更有效,因为 10 int 需要更少的内存并且 std::array 只在堆栈上分配一次而不会导致问题。 这是 std::array:

的解决方案
#include <array>

class A
{
  static constexpr int SIZE = 10;

public:
  A() {}
  void aaa() { std::array<int, SIZE> a; }
};

如果您使用的是 c++11 之前的旧编译器,例如 c++03,您也可以执行 enum {SIZE=10};

class A {
  enum {SIZE=10};

  void aaa() {int a[SIZE];}
};