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

问题描述 投票:1回答:1

我试图创建一个包含字体样式的聪明的类。之前由3个具有逐位兼容值的枚举组成(每组值与其他枚举没有重叠位)所以你可以做FontStyle::LEFT | FontStyle::TOP

但clang警告我关于组合不相关的枚举,是的,我在这里看到了可能的错误:FontStyle::LEFT | FontStyle::RIGHT确实设置了两个位。因此,我使用前一个枚举和模板的辅助类重写了该类,以匹配正确的值。但是现在我的调试版本中有关于undefined reference的clang到我的static constexpr成员的链接错误。

看看Undefined reference error for static constexpr member建议,该值是ODR使用的,但我没有使用任何引用。

When does a static constexpr class member need an out-of-class definition?然后指向我的帮助类的隐式复制构造函数,这是问题。

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

Related code

#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;
}
c++ constexpr static-members
1个回答
0
投票

这条线

FontStyle style = FontStyle::CENTER;

是使用FontStyle::CENTER的ODR。

我试过用

constexpr FontStyle style = FontStyle::CENTER;

但我在构造函数中遇到了问题。以下工作虽然我不清楚这是否可以满足您的需求。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.