16

使用以下代码时,我对链接器错误感到困惑:

// static_const.cpp -- complete code
#include <vector>

struct Elem {
    static const int value = 0;
};

int main(int argc, char *argv[]) {
    std::vector<Elem> v(1);
    std::vector<Elem>::iterator it;

    it = v.begin();
    return it->value;
}

然而,这在链接时会失败——不知何故,它需要一个静态常量“值”的符号。

$ g++ static_const.cpp 
/tmp/ccZTyfe7.o: In function `main':
static_const.cpp:(.text+0x8e): undefined reference to `Elem::value'
collect2: ld returned 1 exit status

顺便说一句,这可以用 -O1 或更好的方式编译;但对于更复杂的情况,它仍然失败。我正在使用 gcc 版本 4.4.4 20100726 (Red Hat 4.4.4-13)。

任何想法我的代码可能有什么问题?

4

6 回答 6

9

如果你想在struct中初始化它,你也可以这样做:

struct Elem {
    static const int value = 0;
};

const int Elem::value;
于 2011-04-01T01:07:29.497 回答
5

尝试将其写为

struct Elem {
    static const int value;
};

const int Elem::value = 0;

etc

.

于 2011-04-01T01:13:29.480 回答
2

static类成员通常应该在一个编译单元中定义在类之外(在内部声明,在外部定义)。

我不记得它是如何与const静态整数成员的内联初始化交互的。

于 2011-04-01T01:14:34.643 回答
2

另请参阅这篇文章:本质上,问题在于编译器最终会以某种方式将您的代码扩展为获取 Elem::value 的地址。

于 2014-01-07T19:12:58.233 回答
1

为什么不这样做呢?

return Elem::value;

但答案是您在声明中分配了一个值。这应该适用于基本类型,例如int, 并且仅对复杂类型(即类,例如如果您有一个字符串而不是 int)是必需的。我在实践中发现,这取决于您使用的编译器的版本。而且,正如您发现的那样,优化级别。

于 2011-04-01T01:16:28.780 回答
1

在大多数定义类内的编译器中都static const <integral type>可以正常工作。但是一些编译器,如 Android NDK,这样的类内定义会导致链接器错误。对于这种情况,我们可以使用类型化enum的 s:

struct X
{
  enum : int64_t { VALUE = 100; }; // == static const int64_t VALUE = 100;
};
于 2020-07-13T06:23:03.843 回答