我使用的是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 header
#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
最佳答案
数组是类成员这一事实是这个难题的重要组成部分。
static constexpr
(在某些情况下,还有const
)类成员有一个特殊的规则,即如果它们从未被 ODR 使用过,则它们不需要定义。但是您的程序确实使用了该变量,因此根据 C++ 标准,您需要一个定义。
2
和 x
之间行为发生变化的原因是,在前一种情况下,优化器能够消除对数组的运行时访问。但您不能依赖此1,规则是如果存在 ODR 使用,则需要定义。
以下是完整规则,可在第 9.4.2 节中找到 ([class.static.data]
):
If a non-volatile
const static
data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment- expression is a constant expression (5.19). Astatic
data member of literal type can be declared in the class definition with theconstexpr
specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. — end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.
在其他情况下,需要进行优化。例如,您可以使用
var = sizeof (char[COORDINATES[0][2][0]]);
这绝不是COORDINATES
的odr使用。但这种保证仅在需要常量表达式的情况下进行,例如在数组绑定(bind)中,而不是一般情况下。
如果您尝试使用负数组界限,当然会出现问题。所以也许您更喜欢:
enum { varc = COORDINATES[0][2][0] };
var = varc;
重点是在绝对必须在编译时评估的上下文中使用它。
关于c++ - constexpr 数组未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25573711/