C++ 对静态constepr成员的未定义引用仅由值使用

C++ 对静态constepr成员的未定义引用仅由值使用,c++,constexpr,static-members,C++,Constexpr,Static Members,我试图创建一个包含字体样式的聪明类。在此之前,它由3个具有逐位兼容值的枚举组成(每组值没有与其他枚举重叠的位),因此您可以执行FontStyle::LEFT>FontStyle::TOP 但clang警告我不要合并不相关的枚举,是的,我在这里看到了可能的bug:FontStyle::LEFT | FontStyle::RIGHT设置了这两个位。因此,我为前面的枚举和模板使用了一个helper类来重新构建该类,以匹配正确的值。但是现在我在调试构建时遇到了链接器错误,关于对我的静态constexpr

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

但clang警告我不要合并不相关的枚举,是的,我在这里看到了可能的bug:
FontStyle::LEFT | FontStyle::RIGHT
设置了这两个位。因此,我为前面的枚举和模板使用了一个helper类来重新构建该类,以匹配正确的值。但是现在我在调试构建时遇到了链接器错误,关于
对我的
静态constexpr
成员的
未定义引用

看一下,这个值是ODR使用的,但我没有使用任何引用

这就指向了我的helper类的隐式复制构造函数,这就是问题所在

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

:

#包括
#包括
名称空间详细信息{
模板
结构FontStylePart
{
constexpr FontStylePart(uint8_t val):值(val){}
uint8_t值;
};
}//名称空间详细信息
类字体样式
{
静态constexpr unsigned AlignH=0;
静态constexpr unsigned AlignV=1;
公众:
constexpr FontStyle()=默认值;
模板
constexpr FontStyle(细节::FontStylePart样式):FontStyle()
{
value[T_index]=style.value;
}
///水平对齐
静态constexpr detail::FontStylePart LEFT=0;
静态constexpr detail::FontStylePart RIGHT=1;
静态constexpr细节::FontStylePart中心=2;
///垂直对齐
静态constexpr detail::FontStylePart TOP=0;
静态constexpr detail::FontStylePart BOTTOM=1;
静态constexpr detail::FontStylePart VCENTER=2;
私人:
数组值={0,0,0};
};
int main(){
FontStyle=FontStyle::CENTER;
返回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

我在代码中没有看到任何子类,因此不清楚ODR使用的确切位置。你能找出MCVE中的问题吗?对不起,在一个地方输入错误。我的意思是helper类不是子类。MCVE在上面发布,带有指向wandbox的链接,其中显示链接器错误。我认为此代码应该可以工作(odr不应该使用
FontStyle::CENTER
)。事实上,当我将编译器更改为Clang8.0时,它会构建并运行。0@Brian不幸的是,你没有把C++标准设置成C++ 14吗?在C++14中,由于上述原因,这不起作用,而在C++17及更高版本中,它起作用。这只是因为调用了FontStylePart的CopyConstructor。如何避免这种情况?C++17允许省略构造函数。
int main() {
   constexpr auto v = FontStyle::CENTER;
   FontStyle style = v;
   return 0;
}