启用c ++ 11后,我遇到了一个奇怪的gcc 4.7问题:
当我想编译时:
constexpr unsigned int getDim(const int e){
return (e==1)? A::Set::Dimension :
(
(e==2)? B::Set::Dimension :
(
(e==3)? C::Set::Dimension :
(
+D::Set::Dimension
)
)
);
}
对于每个结构A,B,C,D
,定义Set
的typedef,其中相关的Set具有int Dimension
,例如
struct SetOne{
static const int Dimension = 1;
}
struct A{
typedef SetOne Set;
}
如果我不使用unary +
前面的D::Set::Dimension
,那么链接器就会抱怨对SetOne :: Dimension的未定义引用。
这与以下问题相同:Undefined reference to static class member
我无法给出MWE,因为一个.cpp文件的简单示例消失了问题。 ? (但是A,B,C,D的所有定义都在一个头文件中)
有没有人知道这里可能出现什么问题?这是不合适的: - )
观察2:
如果用0替换+D::Set::Dimension
,它编译得很好,但是为什么其他语句被A::Set::Dimension
破解不会引起相同的链接错误?
答案 0 :(得分:8)
在您正在构建的表达式中,三元表达式产生左值,这会导致静态常量的 odr-use 。单一定义规则要求 odr-used 的所有静态成员都已定义,因此您需要提供定义(在单个翻译单元中)。
那么为什么问题会随着一元+ +
而消失
一元+
不会导致静态成员的 odr-use ,它只需要一个 rvalue ,其结果是另一个< EM>右值。通过条件运算符级联,因为两个参数中的一个是 rvalue ,表达式的结果也将是 rvalue 。最终结果是单个+
具有强制函数中使用的所有静态函数的左值到右值转换的效果,并删除 odr-uses
如果用0替换:+ D :: Set :: Dimension,则编译正确
同样,0是 rvalue ,它将与上述一元+
具有相同的效果。