【发布时间】:2014-03-10 18:33:42
【问题描述】:
我在启用 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;
}
如果我不使用 D::Set::Dimension 前面的 unary +,链接器将无法抱怨对 SetOne::Dimension 的未定义引用。
这是不是和Undefined reference to static class member一样的问题
我不能给出 MWE,因为对于一个 .cpp 文件的简单示例,问题就消失了。 ? (但 A、B、C、D 的所有定义都在一个头文件中)
有人知道这里可能出了什么问题吗?这是不直观的:-)
观察 2:
如果将:+D::Set::Dimension 替换为 0,则编译正常,但为什么将其他语句破解为 A::Set::Dimension 不会出现相同的链接错误?
【问题讨论】:
-
是的,您对先前回答的问题的假设似乎是正确的。
static const int Dimension = 1;内部类声明只是一个静态变量声明,而不是定义(尽管初始化)。您应该在声明之外显式定义类的静态成员。 -
如果我在 cpp 文件中定义类声明之外的静态成员,那么我不能在模板函数
f<Set::Dimension>中使用静态 int,因为编译器需要查看 const 表达式...?我怎样才能避免这种情况? -
如果您仅将整型静态变量用于此类目的,您可以在类中初始化它们并在类之外创建它们的定义而无需任何初始化。 初始化和定义不一样。如果你会使用C++11你也可以尝试使用
constexpr关键字。