静态const int成员和未定义的引用

static const int member and undefined reference

本文关键字:未定义 引用 成员 const int 静态      更新时间:2023-10-16

我使用gcc 4.7.3 for ARM平台来编译我的代码。我有几个这样的课程:

// types.h
enum Types
{
    kType1,
    kType2
    // ...
};
// d1.h
class D1 : public Base
{
public:
    static const int type = kType1;
    // ...
};
// d2.h
class D2 : public Base
{
public:
    static const int type = kType2;
    // ...
};

在资源的某个地方,我使用这些类:

MyObject obj;
doSomething<D1>(obj);
doSomething<D2>(obj);
// other.cpp
class Foo
{
    template<typename T>
    void doSomething(MyObject obj)
    {
        mm_.insert(std::multimap<int, MyObject>::value_type(T::type, obj));
    }
};

并获取下一条消息(在链接过程中):

undefined reference to `D1::kType`
undefined reference to `D2::kType`
// more messages of this type

好的。如果我像这样更改do_something函数:

template<typename T>
void doSomething(MyObject obj)
{
    mm_.insert(std::multimap<int, MyObject>::value_type( (int) T::type, obj));
}

它编译得还可以。但是为什么呢?在标准中找不到任何关于它的信息。有人知道发生了什么吗?

谢谢。

p.S.

此修复

 // d1.cpp
 const int D1::kType;

同样有效,但这是意料之中的事。

附言:如果使用对T::type的引用或指针,答案会很明显,但我看不到任何需要ref或ptr的东西。AFAIK std::multimap::value_type按值(不是ref,也不是ptr)获取参数。

// d1.cpp
const int D1::kType;
// d2.cpp
const int D2::kType;

是答案吗,

//d1.h
public:
    static const int type = kType1;

就像函数原型一样,它被编译到包括标头的每个复杂对象(cpp文件)中,因此由于ODR规则,它实际上并没有保留内存空间,否则链接器会在包括标头的每一个编译单元中找到该变量的许多实例。

因此,您需要一个编译单元(一个cpp文件),它定义了将用于在多次使用的标头中找到的类常量的实际内存空间。