2014-08-29 37 views
2

我与C++ 11。我正在尝试初始化一个多维数组。第一次尝试是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}}}; 

编译器抱怨一个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行是坐标的第二次使用

我的完整代码,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

您在定义坐标之前包含shape.h! – Christophe 2014-08-29 18:01:52

+0

@Christophe我看不出有什么问题...坐标只是在LShape中,而不是形状 – 2014-08-29 18:05:54

+0

@Piotr S.我在Linux中使用默认编译器(GCC)IDE使用以下命令 g ++ -std = C++ 11 -c -g -MMD -MP -MF“build/Debug/GNU-Linux-x86/src/shape/LShape.od”-o build/Debug/GNU-Linux-x86/src /shape/LShape.o src/shape/LShape.cpp – 2014-08-29 18:12:21

回答

4

该阵列是一个类的成员,这一事实是重要的部分这个谜题。

static constexpr(在某些情况下,还有const)类成员有一个特殊规则,即如果它们从不使用odr,则它们不需要定义。但是你的程序不会使用变量,所以根据C++标准,你需要一个定义。

原因2x之间的行为改变的是,在前者的情况下优化能够消除阵列运行时的访问。但是你不能依赖这个,规则是如果有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). A static data member of literal type can be declared in the class definition with the constexpr 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]]); 

这是从来没有的ODR使用的COORDINATES。但是,只有在需要常量表达式的情况下才能做出这种保证,例如在数组绑定中,而不是一般情况下。

当然,如果您尝试使用负数组绑定,则会出错。所以,你可能更喜欢:

enum { varc = COORDINATES[0][2][0] }; 
var = varc; 

这个观点在绝对必须在编译时评估的上下文中使用它。

+0

我把constexpr const int LShape :: COORDINATES [4] [4] [2];在标题的末尾,现在编译。希望它不会给更多的问题,哈哈。感谢您的解释。 – 2014-08-29 18:23:23

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 
} 

编译代码我用下面的编译器编译它成功:

  • C++在线(GNU GCC版本4.8.1)
  • C++ 11在线(GNU GCC版本4.7.2)