constexpr数组未定义

时间:2014-08-29 17:56:31

标签: c++ arrays c++11 constexpr

我用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

2 个答案:

答案 0 :(得分:4)

数组是类成员的事实是这个难题的重要部分。

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

2x之间行为发生变化的原因是,在前一种情况下,优化器能够消除对阵列的运行时访问。但是你不能依赖这个 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
}

我使用以下编译器成功编译了它:

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