内联函数中的未定义引用,用一元+求解

时间:2014-03-10 18:33:42

标签: c++ c++11 static linker

启用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破解不会引起相同的链接错误?

1 个答案:

答案 0 :(得分:8)

在您正在构建的表达式中,三元表达式产生左值,这会导致静态常量的 odr-use 。单一定义规则要求 odr-used 的所有静态成员都已定义,因此您需要提供定义(在单个翻译单元中)。

  

那么为什么问题会随着一元+ +

而消失

一元+不会导致静态成员的 odr-use ,它只需要一个 rvalue ,其结果是另一个< EM>右值。通过条件运算符级联,因为两个参数中的一个是 rvalue ,表达式的结果也将是 rvalue 。最终结果是单个+具有强制函数中使用的所有静态函数的左值到右值转换的效果,并删除 odr-uses

  

如果用0替换:+ D :: Set :: Dimension,则编译正确

同样,0是 rvalue ,它将与上述一元+具有相同的效果。