简体   繁体   中英

static const int member and undefined reference

I use gcc 4.7.3 for ARM platform to compile my code. I have several classes like this:

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

Somewhere in the sources I use those classes:

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

And get the next messages (during linking):

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

OK. If I change do_something function like this:

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

it compiles OK. But why? Can't find anything in the standard about it. Does anybody have ideas about what's going on?

Thanks.

PS

This fix

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

also works, but this is expected.

PPS the answer would be quite obvious in case of using reference or pointer to T::type, but I don't see anything that requires a ref or ptr. AFAIK std::multimap::value_type take the arguments by value (not ref, nor ptr).

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

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

is the answer,

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

Is like a function prototype, it is compiled into every complication object (cpp file) that includes the header, and so because of the ODR rule it doesn't actually reserve the memory space, or else the linker would find lots of instances of the variable in every compilation unit which included the header.

You therefore need one compilation unit (a cpp file) which defines the actual memory space that will be used for the class constant found in the header that is used multiple times.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM