C++ 静态常量int成员和未定义的引用

C++ 静态常量int成员和未定义的引用,c++,gcc,c++11,linker,static-members,C++,Gcc,C++11,Linker,Static Members,我使用用于ARM平台的GCC4.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 in

我使用用于ARM平台的GCC4.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;
    // ...
};
template<typename T>
void doSomething(MyObject obj)
{
    mm_.insert(std::multimap<int, MyObject>::value_type( (int) T::type, obj));
}
在源代码的某个地方,我使用了这些类:

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));
    }
};
嗯。如果我更改了,请执行以下操作:

// 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;
    // ...
};
template<typename T>
void doSomething(MyObject obj)
{
    mm_.insert(std::multimap<int, MyObject>::value_type( (int) T::type, obj));
}
也可以,但这是意料之中的

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

答案是,

//d1.h
public:
    static const int type = kType1;
就像一个函数原型,它被编译到包含头的每个复杂对象(cpp文件)中,因此由于ODR规则,它实际上没有保留内存空间,否则链接器会在包含头的每个编译单元中找到大量变量实例

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

答案是,

//d1.h
public:
    static const int type = kType1;
就像一个函数原型,它被编译到包含头的每个复杂对象(cpp文件)中,因此由于ODR规则,它实际上没有保留内存空间,否则链接器会在包含头的每个编译单元中找到大量变量实例


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

您不应该引用t::type而不是t::kType吗?@TimoGeusch,是的,谢谢。你确定Timo所指出的并不能解决问题吗?由于链接器似乎在寻找
D1::kType
,这正是您的模板所要求的。@MatstPeterson,这只是问题中的一个输入错误。真正的代码使用正确的成员。
std::multimap::value\U type
std::pair
,其构造函数采用
const&T,const&U
。FWIW.你不应该引用t::type而不是t::kType吗?@TimoGeusch,是的,谢谢。你确定Timo所指出的并不能解决问题吗?由于链接器似乎在寻找
D1::kType
,这正是您的模板所要求的。@MatstPeterson,这只是问题中的一个输入错误。真正的代码使用正确的成员。
std::multimap::value\U type
std::pair
,其构造函数采用
const&T,const&U
。不管好坏