对静态constexpr数据成员的未定义引用错误



我很困惑这里出了什么问题。我得到了一个未定义的数组引用错误,我以与其他两个数组相同的方式定义了这个数组,它们没有在代码中的其他地方抛出错误。

undefined reference to `shift7seg::numbers'

shift7seg.cpp代码,显示使用的类似定义数组的其他函数

uint8_t shift7seg::convert_char(const char& OGchar){
uint8_t converted;
switch (OGchar){
case 'A':
converted = capital[0];
break;
case 'h':
converted = lower[3];
break;
//more cases removed for posting
}
return converted;
}
uint8_t shift7seg::convert_num(const uint8_t& OGnum){
uint8_t converted;
if(OGnum<10){
converted = numbers[OGnum];
}
else{
converted = blank;
}
return converted;
}

shift7seg.h显示了正在使用的阵列的定义

class shift7seg{
public:
//constructor, choose pins to use as well as display size
shift7seg(const uint8_t _dataPin,
const uint8_t _latchPin,
const uint8_t _clkPin,
const uint8_t _num_digits);
static constexpr uint8_t numbers[10] =               // 7 segment values for decimals 0..9
{
//TRUTH TABLE    |   0 = segment on
//ABCDEFGH       |   1 = segment off
B00000011,  //0  |        A
B10011111,  //1  |      -----
B00100101,  //2  |   F |     | B
B00001101,  //3  |     |  G  |
B10011001,  //4  |      -----
B01001001,  //5  |   E |     | C
B01000001,  //6  |     |     |
B00011111,  //7  |      -----
B00000001,  //8  |        D
B00011001       //9  |
};
static constexpr uint8_t capital[13] =
{
B00010001,  //A or R, 0
B00000001,  //B 1
B01100011,  //C 2
B00000011,  //D or O, 3
B01100001,  //E 4
B01110001,  //F 5
B01000001,  //G 6
B10010001,  //H 7
B10000111,  //J 8
B11100011,  //L 9
B00110001,  //P 10
B01001001,  //S 11
B10000011  //U or V, 12
};
static constexpr uint8_t lower[9] =
{
B11000001,  //b 0
B11100101,  //c 1
B10000101,  //d 2
B11010001,  //h 3
B10011111,  //l 4
B11010101,  //n 5
B11000101,  //o 6
B11110101,  //r 7
B11000111   //u or v, 8
};

方言是C++11我一辈子都搞不清楚自己做错了什么。到目前为止,与橡皮鸭交谈没有任何效果。

这里有更多的错误代码。

more undefined references to `shift7seg::numbers' follow
collect2.exe: error: ld returned 1 exit status
exit status 1

在代码的某个地方,您使用numbers进行ODR,但您没有它的定义。

这是你的问题的一个简单版本(魔杖盒(:

#include <iostream>
#include <cstdint>
class shift7seg {
public:
static constexpr std::uint8_t numbers[10] = {};
};
int main() {
// taking the address is ODR-use
std::cout << &shift7seg::numbers[0] << 'n';
}

可能的解决方案是

  1. 使用-std=c++17(或更高版本(编译,其中所有static constexpr数据成员都是隐式inline,不需要越界定义

  2. 在实现文件(shift7seg.cpp(中添加一个行外定义,如下所示(wandbox(:

constexpr std::uint8_t shift7seg::numbers[10];

首先,我认为这些二进制文字中的前缀是0B,而不是B。其次,您需要c++17来编译它,因为有静态constexpr的东西。

报价

如果静态数据成员被声明为constexpr,那么它是隐式内联的,不需要在命名空间范围内重新声明。这种不带初始值设定项的重新声明(以前如上所示是必需的(仍然是允许的,但已被弃用。

来自https://en.cppreference.com/w/cpp/language/static

最新更新