如何使用 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::vector
和 std::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];}
};
我尝试使用 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::vector
和 std::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];}
};