我正在开发一个内核,我想创建我的静态数据成员constexpr
,这样我就可以将其值放在enum class
中。但是,如果我这样做,我会得到一个未定义的引用错误。如果我把它变成非constexpr并在类之外初始化它,它似乎才有效。
工作:
// terminal.hpp
class Terminal
{
static uint32_t col_map[16];
};
// terminal.cpp
uint32_t Terminal::col_map[16] = {
0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
};
不工作:
// terminal.hpp
class Terminal
{
constexpr static uint32_t col_map[16] = {
0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
};
enum class Color : uint32_t
{
Black = col_map[0],
White = col_map[15]
};
};
请注意,我试图在常规编译器上重现这一点失败,所以我认为它与内核或交叉编译器有关。
链接错误:
terminal.o: In function `Terminal::drawcolormap()':
terminal.cpp:(.text+0x6f): undefined reference to `Terminal::col_map'
我总是运行make clean; make
。
答案 0 :(得分:7)
静态数据成员应在类外定义,如果它是使用过的--- 期间。这条规则没有例外。
如果数据成员是constexpr
,则还必须在里面初始化类定义。但是,这并没有废除在类外定义它的要求。
正确的代码:
class Terminal
{
constexpr static uint32_t col_map[16] = { /* ... */ };
// ...
};
constexpr uint32_t Terminal::col_map[16]; // definition
这是违反直觉的,但这就是它的方式。