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

use*_*984 3 c++ c++11

我正在研究一个内核,我想创建我的静态数据成员,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
};
Run Code Online (Sandbox Code Playgroud)

不工作:

// 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]
    };  
};
Run Code Online (Sandbox Code Playgroud)

请注意,我试图在常规编译器上重现这一点失败,所以我认为它与内核或交叉编译器有关.

链接器错误:

terminal.o: In function `Terminal::drawcolormap()':
terminal.cpp:(.text+0x6f): undefined reference to `Terminal::col_map'
Run Code Online (Sandbox Code Playgroud)

我总是跑make clean; make.

Bri*_*ian 7

如果静态数据成员使用了od-used --- period,则应在类外定义.这条规定没有例外.

在数据成员的情况下constexpr,它也必须类定义中初始化.但是,这并没有废除在课堂外定义它的要求.

正确的代码:

class Terminal
{
    constexpr static uint32_t col_map[16] = { /* ... */ };
    // ...
};
constexpr uint32_t Terminal::col_map[16]; // definition
Run Code Online (Sandbox Code Playgroud)

这是违反直觉的,但这就是它的方式.