user2466803
user2466803

Reputation: 265

initialize map with static member variable

I do not understand why I cannot use a public const static member of a class in the initializer list of a map (probably any container). As I understand it "MyClass::A" is an rvalue, it seems like it should be the exact same as the case where I am using "THING" which is also a static const just outside of a class.

Here is the error:

Undefined symbols for architecture x86_64:
  "MyClass::A", referenced from:
      _main in map-380caf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

And here is the code:

#include <iostream>
#include <map>
#include <string>

static const int THING = 1;

class MyClass {
public:
    static const int A = 1;
};

int
main()
{
    int a;
    typedef std::map<int, std::string> MyMap;

    // compiles and works fine
    a = MyClass::A;
    std::cout << a << std::endl;

    // compiles and works fine
    MyMap other_map = { {THING, "foo"} };
    std::cout << other_map.size() << std::endl;

    // Does not compile
    MyMap my_map = { {MyClass::A, "foo"} };
    std::cout << my_map.size() << std::endl;

    return 0;
}

UPDATE 1:

Using clang on OS X:

Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

compiler flags:

clang++ map.cc -std=c++1y

Upvotes: 3

Views: 293

Answers (1)

Zan Lynx
Zan Lynx

Reputation: 54363

Something in the map code probably tried to take the address of a reference to your int.

The class definition here:

class MyClass {
public:
    static const int A = 1;
};

does not actually create any memory for A. In order to do that you have to do in the header file:

class MyClass {
public:
    static const int A;
};

and in a CPP file:

const int MyClass::A = 1;

Or I guess with the newest C++ versions you can leave the = 1 in the header and just declare the storage in the CPP file with:

const int MyClass::A;

Upvotes: 2

Related Questions