对静态 constexpr 成员的未定义引用仅由值使用

Undefined reference to static constexpr member only used by value

本文关键字:引用 未定义 静态 constexpr 成员      更新时间:2023-10-16

我试图创建一个包含字体样式的聪明类。在此之前,它由 3 个具有按位兼容值的枚举组成(每组值与其他枚举没有重叠位),因此您可以执行FontStyle::LEFT | FontStyle::TOP

但是 clang 警告我不要组合不相关的枚举,是的,我在这里看到了可能的错误:FontStyle::LEFT | FontStyle::RIGHT确实设置了这两个位。因此,我使用以前的枚举和模板的帮助程序类重新设计了该类,以匹配正确的值。但是现在我在调试构建上的 clang 收到链接器错误,大约undefined reference我的static constexpr成员。

查看静态 constexpr 成员的未定义引用错误表明,该值是 ODR 使用的,但我没有使用任何引用。

静态 constexpr 类成员何时需要类外定义? 然后,这将我指向我的帮助程序类的隐式复制构造函数,这就是问题所在。

我是否有机会避免 C++14(C++17 已经允许省略它们)和调试构建(Ctors 在发布中进行了优化,因此没有未定义的引用)中的类外定义?

相关代码:

#include <array>
#include <cstdint>
namespace detail {
template<unsigned T_index>
struct FontStylePart
{
constexpr FontStylePart(uint8_t val) : value(val) {}
uint8_t value;
};
} // namespace detail
class FontStyle
{
static constexpr unsigned AlignH = 0;
static constexpr unsigned AlignV = 1;
public:
constexpr FontStyle() = default;
template<unsigned T_index>
constexpr FontStyle(detail::FontStylePart<T_index> style) : FontStyle()
{
value[T_index] = style.value;
}
/// Horizontal align
static constexpr detail::FontStylePart<AlignH> LEFT = 0;
static constexpr detail::FontStylePart<AlignH> RIGHT = 1;
static constexpr detail::FontStylePart<AlignH> CENTER = 2;
/// Vertical align
static constexpr detail::FontStylePart<AlignV> TOP = 0;
static constexpr detail::FontStylePart<AlignV> BOTTOM = 1;
static constexpr detail::FontStylePart<AlignV> VCENTER = 2;
private:
std::array<uint8_t, 3> value = {{0, 0, 0}};
};
int main() {
FontStyle style = FontStyle::CENTER;
return 0;
}

FontStyle style = FontStyle::CENTER;

是 ODR 对FontStyle::CENTER的使用。

我试过使用

constexpr FontStyle style = FontStyle::CENTER;

但我在构造函数中遇到了问题。以下内容有效,尽管我不清楚这是否可以满足您的需求。

int main() {
constexpr auto v = FontStyle::CENTER;
FontStyle style = v;
return 0;
}

这会将 ODR 使用的责任转移到constexpr auto v.