对静态 constexpr 数据成员的未定义引用错误
Undefined reference error to static constexpr data member
我很困惑这里出了什么问题。
我收到一个数组的未定义引用错误,我的定义方式与其他两个数组的定义方式相同,它们不会在代码的其他地方抛出错误。
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
首先,我认为那些二进制文字中的前缀是 0B
,而不是 B
。其次,由于静态 constexpr 的东西,你需要 c++17 来编译它。
引用
如果静态数据成员声明为 constexpr,则它是隐式内联的,不需要在命名空间范围内重新声明。这种没有初始化器的重新声明(如上所示以前是必需的)仍然允许,但已弃用。
在您的代码中某处您是 ODR-using numbers
但您没有定义它。
这是您问题的简单版本 (wandbox):
#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';
}
可能的解决方案是
使用 -std=c++17
(或更高版本)编译,其中所有 static constexpr
data members are implicitly inline
不需要外联定义
在您的实现文件 (shift7seg.cpp) 中添加一个外联定义,如下所示 (wandbox):
constexpr std::uint8_t shift7seg::numbers[10];
我很困惑这里出了什么问题。 我收到一个数组的未定义引用错误,我的定义方式与其他两个数组的定义方式相同,它们不会在代码的其他地方抛出错误。
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
首先,我认为那些二进制文字中的前缀是 0B
,而不是 B
。其次,由于静态 constexpr 的东西,你需要 c++17 来编译它。
引用
如果静态数据成员声明为 constexpr,则它是隐式内联的,不需要在命名空间范围内重新声明。这种没有初始化器的重新声明(如上所示以前是必需的)仍然允许,但已弃用。
在您的代码中某处您是 ODR-using numbers
但您没有定义它。
这是您问题的简单版本 (wandbox):
#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';
}
可能的解决方案是
使用
-std=c++17
(或更高版本)编译,其中所有static constexpr
data members are implicitlyinline
不需要外联定义在您的实现文件 (shift7seg.cpp) 中添加一个外联定义,如下所示 (wandbox):
constexpr std::uint8_t shift7seg::numbers[10];