我试图创建一个包含字体样式的聪明类。在此之前,它包含3个枚举,每个枚举具有按位兼容的值(每个值集与其他枚举没有重叠的位),因此您可以进行FontStyle::LEFT | FontStyle::TOP
但是clang警告我不要合并不相关的枚举,是的,我在这里看到了可能的错误:FontStyle::LEFT | FontStyle::RIGHT
确实设置了两个位。因此,我对以前的枚举和模板使用了一个帮助器类来对该类进行重做,以匹配正确的值。但是现在,我在undefined reference
成员的static constexpr
成员的Debug版本中收到了有关clang的链接器错误。
从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构建(Ctor在Release中得到了优化,因此没有未定义的引用)?
#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;
}
答案 0 :(得分: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
。