c++ - constexpr 数组未定义

标签 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 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++ 标准,您需要一个定义。

2x 之间行为发生变化的原因是,在前一种情况下,优化器能够消除对数组的运行时访问。但您不能依赖此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). 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]]);

这绝不是COORDINATES的odr使用。但这种保证仅在需要常量表达式的情况下进行,例如在数组绑定(bind)中,而不是一般情况下。

如果您尝试使用负数组界限,当然会出现问题。所以也许您更喜欢:

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

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

关于c++ - constexpr 数组未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25573711/

相关文章:

php - 如何在 PHP 的 while 循环中分割返回的结果

php - 使用 PHP 将 Linux 命令的结果输出到表中

c++ - initializer_list函数重载的解决

c++ - "not declared in this scope"错误的问题

C++ libPNG - 简单的初始化错误

c++ - 右值引用成员变量有什么用

c++ - 在 istream 中包装 vector<char> 时,tellg 和 seekg 不工作

c++ - 如何一次包含所有的 C++ 标准库?

javascript - 如何在Javascript中将问号包围的文本提取到数组中

c++ - 智能指针的转换