【问题标题】:static const int member and undefined referencestatic const int 成员和未定义的引用
【发布时间】:2013-07-01 07:27:11
【问题描述】:

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

// 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));
}

编译正常。但为什么?在标准中找不到任何关于它的内容。有人对发生的事情有想法吗?

谢谢。

附言

这个修复

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

也可以,但这是意料之中的。

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

【问题讨论】:

  • 你不应该引用 T::type 而不是 T::kType?
  • @TimoGeusch,是的,谢谢。固定
  • 您确定 Timo 指出的内容并不能真正解决问题吗?因为看起来链接器正在寻找D1::kType,这正是您的模板所要求的。
  • @MatsPetersson,这只是问题中的一个错字。真正的代码使用正确的成员。
  • std::multimap&lt;T,U&gt;::value_typestd::pair&lt;const T,U&gt;,其构造函数采用const&amp; T, const&amp; U。 FWIW。

标签: c++ gcc c++11 linker static-members


【解决方案1】:
// d1.cpp
const int D1::kType;

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

就是答案,

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

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

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

【讨论】:

    猜你喜欢
    • 2011-07-27
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    相关资源
    最近更新 更多