我用c ++ 11。我试图初始化一个多维数组。第一次尝试是
const static int COORDINATES[4][4][2]={{{-1,-1},{0,0},{1,1},{2,0}},
{{-1,1},{0,0},{1,-1},{0,-2}},
{{1,1},{0,0},{-1,-1},{-2,0}},
{{1,-1},{0,0},{-1,1},{0,2}}};
编译器抱怨constexpr,所以我写了
constexpr const static int COORDINATES[4][4][2]={{{-1,-1},{0,0},{1,1},{2,0}},
{{-1,1},{0,0},{1,-1},{0,-2}},
{{1,1},{0,0},{-1,-1},{-2,0}},
{{1,-1},{0,0},{-1,1},{0,2}}};
没有错误,但是当我在方法中使用数组时,会出错。我不明白......
void LShape::rotateShape(Square* cloneSquares) {
int var=COORDINATES[1][1][1]; //no problems
int x=2;
var=COORDINATES[0][x][0]; //error 'not defined' because of x
//if changed to number, works
}
错误:
LShape.cpp:23: referencia a `LShape::COORDINATES' sin definir //reference to L...S not defined
第23行是第二次使用COORDINATES
我的完整代码,LShape标题
#ifndef LSHAPE_H
#define LSHAPE_H
#include "Square.h"
#include "EmptySquare.h"
#include "Shape.h"
class LShape : public Shape {
public:
LShape();
LShape(const LShape& orig);
virtual ~LShape();
inline int getState() {return state;}
inline int getNUMBER_OF_STATES() {return NUMBER_OF_STATES;}
inline int getNUMBER_OF_SQUARES() {return NUMBER_OF_SQUARES;}
void rotateShape(Square* cloneSquares);
private:
int state;
static const int NUMBER_OF_STATES=4;
static const int NUMBER_OF_SQUARES=4;
constexpr const static int INITIAL_COORDINATES[3][2]={{1,0},{1,0},{1,1}};
constexpr const static int COORDINATES[4][4][2]={{{-1,-1},{0,0},{1,1},{2,0}},
{{-1,1},{0,0},{1,-1},{0,-2}},
{{1,1},{0,0},{-1,-1},{-2,0}},
{{1,-1},{0,0},{-1,1},{0,2}}};
};
#endif /* LSHAPE_H */
LShape代码
#include "../../include/LShape.h"
LShape::LShape() : Shape(){
//numberSquares=4;
//squares = new Square[numberSquares];
}
LShape::~LShape(){
//dtor
}
LShape::LShape(const LShape& other){
//copy ctor
}
void LShape::rotateShape(Square* cloneSquares) {
int var=COORDINATES[1][1][1]; //no problems
int x=2;
var=COORDINATES[0][x][0]; //error not defined
}
顺便说一句,我是C ++的新手,对我不好:)
编辑:我使用linux(GCC)中的默认编译器,IDE正在使用以下命令
g++ -std=c++11 -c -g -MMD -MP -MF "build/Debug/GNU-Linux-x86/src/shape/LShape.o.d" -o build/Debug/GNU-Linux-x86/src/shape/LShape.o src/shape/LShape.cpp
答案 0 :(得分:4)
数组是类成员的事实是这个难题的重要部分。
static constexpr
(在某些情况下,还有const
)班级成员有一个特殊规则,即如果他们从不使用过,他们就不需要定义。但是你的程序会使用变量,因此根据C ++标准你需要一个定义。
2
和x
之间行为发生变化的原因是,在前一种情况下,优化器能够消除对阵列的运行时访问。但是你不能依赖这个 1 ,规则是如果有使用odr则需要定义。
以下是第9.4.2节([class.static.data]
)中的完整规则:
如果非易失性
const static
数据成员是整数或枚举类型,则其在类定义中的声明可以指定大括号或等于初始值,其中每个 initializer-clause 是赋值 - 表达式是一个常量表达式(5.19)。可以使用static
说明符在类定义中声明文字类型的constexpr
数据成员;如果是这样,它的声明应指定一个大括号或等于初始化,其中作为赋值表达式的每个 initializer-clause 是一个不断表达。 [注意:在这两种情况下,成员可能会出现在常量表达式中。 - 结束注释] 如果程序中使用了odr-used(3.2),并且命名空间范围定义不包含初始值设定项,则仍应在命名空间范围内定义该成员。
在其他情况下,需要优化 。例如,您可以使用
var = sizeof (char[COORDINATES[0][2][0]]);
这绝不是COORDINATES
的使用方法。但是这种保证仅在需要常量表达式的情况下进行,例如在数组绑定中,而不是一般情况下。
如果您尝试使用负数组绑定,当然会出错。所以也许你更喜欢:
enum { varc = COORDINATES[0][2][0] };
var = varc;
关键是在上下文中使用它,绝对必须在编译时进行评估。
答案 1 :(得分:0)
我删除了'constexpr'并能够在http://www.compileonline.com/compile_cpp_online.php
编译代码const static int COORDINATES[4][4][2]={{{-1,-1},{0,0},{1,1},{2,0}},
{{-1,1},{0,0},{1,-1},{0,-2}},
{{1,1},{0,0},{-1,-1},{-2,0}},
{{1,-1},{0,0},{-1,1},{0,2}}};
void LShape_rotateShape()
{
int var=COORDINATES[1][1][1]; //no problems
int x=2;
var=COORDINATES[0][x][0]; //error not defined
}
我使用以下编译器成功编译了它: